我有下面的LINQ to SQL方法需要過多的時間來執行,但其SQL對手是相當簡單和快速。我在LINQ部分做錯了什麼?我只是試圖在數據網格中返回一些數據以顯示,只讀。爲什麼這個LINQ比SQL對應的要慢得多?
我明白,如果該工具不適合不要使用它,因此我可以在這裏做一個SQL調用,但我想了解爲什麼會有這樣的差異。
下面是LINQ,然後是它轉儲的SQL。
public static DataTable GetEnrolledMembers(Guid workerID)
{
using (var DB = CmoDataContext.Create())
{
var AllEnrollees = from enrollment in DB.tblCMOEnrollments
where enrollment.CMOSocialWorkerID == workerID || enrollment.CMONurseID == workerID
join supportWorker in DB.tblSupportWorkers on enrollment.EconomicSupportWorkerID
equals supportWorker.SupportWorkerID into workerGroup
from worker in workerGroup.DefaultIfEmpty()
select
new
{
enrollment.ClientID,
enrollment.CMONurseID,
enrollment.CMOSocialWorkerID,
enrollment.EnrollmentDate,
enrollment.DisenrollmentDate,
ESFirstName = worker.FirstName,
ESLastName = worker.LastName,
ESPhone = worker.Phone
};
var result = from enrollee in AllEnrollees.AsEnumerable()
where (enrollee.DisenrollmentDate == null || enrollee.DisenrollmentDate > DateTime.Now)
let lastName = BLLConnect.MemberLastName(enrollee.ClientID)
let firstName = BLLConnect.MemberFirstName(enrollee.ClientID)
orderby enrollee.DisenrollmentDate ascending , lastName ascending
select new
{
enrollee.ClientID,
LastName = lastName,
FirstName = firstName,
NurseName = BLLAspnetdb.NurseName(enrollee.CMONurseID),
SocialWorkerName = BLLAspnetdb.SocialWorkerName(enrollee.CMOSocialWorkerID),
enrollee.EnrollmentDate,
enrollee.DisenrollmentDate,
ESWorkerName = enrollee.ESFirstName + " " + enrollee.ESLastName,
enrollee.ESPhone
};
DB.Log = Console.Out;
return result.CopyLinqToDataTable();
}
}
和SQL:
SELECT [t0].[ClientID], [t0].[CMONurseID], [t0].[CMOSocialWorkerID], [t0].[EnrollmentDate], [t0].[DisenrollmentDate], [t1].[FirstName] AS [ESFirstName], [t1].[LastName] AS [ESLastName], [t1].[Phone] AS [ESPhone]
FROM [dbo].[tblCMOEnrollment] AS [t0]
LEFT OUTER JOIN [dbo].[tblSupportWorker] AS [t1] ON [t0].[EconomicSupportWorkerID] = ([t1].[SupportWorkerID])
WHERE ([t0].[CMOSocialWorkerID] = @p0) OR ([t0].[CMONurseID] = @p1)
-- @p0: Input UniqueIdentifier (Size = 0; Prec = 0; Scale = 0) [060632ee-be09-4057-b17b-2d0190d0ff74]
-- @p1: Input UniqueIdentifier (Size = 0; Prec = 0; Scale = 0) [060632ee-be09-4057-b17b-2d0190d0ff74]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.4926
謝謝你的幫助。你是對的,'BLLConnect.MemberLastName()'在你的文章中造成問題,說沒有SQL對應。另外,我不確定你想用'workerGroup.DefaultIfEmpty()'中的工作人員向我展示什麼。' – 2010-10-06 18:40:56
剛剛編輯出'from workerGroup.DefaultIfEmpty()'/那裏是mystake。 Re BllConnect.MemberLastName(),這就是當你取出AsEnumerable時應該得到的版本。這正是問題所在,通過使用AsEnumerable或任何您可能正在做的事情,您正在導致在服務器上執行linq查詢的一部分。 – eglasius 2010-10-06 18:48:26
我建議用它的內聯等效替換BLLConnect.MemberLastName,所以linq2sql在sql方面做它。另外請確保您以後所做的任何調用都不會再次打到任何外部資源/數據庫,因爲這些將調用每行。 – eglasius 2010-10-06 18:50:56