包含OR子句时LINQ查询的性能问题

时间:2011-12-05 01:30:15

标签: linq entity-framework linq-to-entities

当下面的注释行包含在查询中时,以下LINQ to Entities查询会大幅减慢。有没有更好的方式来表达这个?

'OR'条款只应考虑以下几行:

((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID)) 
|| ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity)(o.Item_ID == o1.Opportunity_ID)) 

完整查询

return withItemsPending
                       ? (from l1 in db.Leads
                          from o1 in db.Opportunities.Where(x => (x.Lead_ID == l1.Lead_ID) && (x.Company_ID == companyId)).DefaultIfEmpty()
                          from l2
                              in
                              db.Tasks.Where(
                                  o =>
                                  ((o.IsCompleted ?? false) == false) &&
                                  (o.TaskType_ID == typeId) &&
                                  ((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID)) 
                                  //|| ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity) && (o.Item_ID == o1.Opportunity_ID)) 
                                  &&
                                  (o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1)))


                          where (l1.Company_ID == companyId)
                          select l1)


                       : (from l1 in db.Leads where (0 == 1) select l1);
        }

以下是违规查询:

SELECT     Extent1.Lead_ID
FROM         Leads AS Extent1 LEFT OUTER JOIN
                      Opportunities AS Extent2 ON Extent2.Lead_ID = Extent1.Lead_ID AND Extent2.Company_ID = 118 INNER JOIN
                      Tasks AS Extent3 ON 0 = (CASE WHEN ([Extent3].[IsCompleted] IS NULL) THEN CAST(0 AS bit) ELSE [Extent3].[IsCompleted] END) AND Extent3.TaskType_ID = 1 AND 
                      5 = Extent3.Type_ID AND Extent3.Item_ID = Extent1.Lead_ID OR
                      4 = Extent3.Type_ID AND Extent3.Item_ID = Extent2.Opportunity_ID AND Extent3.Due_Date > DATEADD(day, - 1, SysDateTime())
WHERE     (Extent1.Company_ID = 118)

1 个答案:

答案 0 :(得分:1)

如果你想要的是“给我未完成的项目,并且比昨天晚些时候到期并且是先行或机会”,你需要在你想要的2个语句周围添加额外的括号。你现在所说的是“给我一些未完成的项目和领导或机会并且比昨天晚到期”。

代码将如下:

return withItemsPending
                       ? (from l1 in db.Leads
                          from o1 in db.Opportunities.Where(x => (x.Lead_ID == l1.Lead_ID) && (x.Company_ID == companyId)).DefaultIfEmpty()
                          from l2
                              in
                              db.Tasks.Where(
                                  o =>
                                  ((o.IsCompleted ?? false) == false) &&
                                  (o.TaskType_ID == typeId) &&
                                  (((o.Type_ID == (int) RecordEnums.RecordType.Lead) && (o.Item_ID == l1.Lead_ID)) 
                                  || ((o.Type_ID == (int)RecordEnums.RecordType.Opportunity) && (o.Item_ID == o1.Opportunity_ID)))
                                  &&
                                  (o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1)))


                          where (l1.Company_ID == companyId)
                          select l1)


                       : (from l1 in db.Leads where (0 == 1) select l1);
        }