我有下面的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