优化LINQ到对象查询

时间:2012-10-22 15:11:00

标签: c# .net performance linq optimization

我正在尝试优化以下LINQ查询以提高其速度性能。它搜索的对象数量可能达到数万个。

var lQuery = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate && (
                (oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll) ?
                   (o.oSalesEvent.EventStateID == ApprovedID || o.oSalesEvent.EventStateID == PendingID) : 
                   o.oSalesEvent.EventStateID == ApprovedID)) &&
      ((oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll) ? 
                (o.oSalesMan.oEmployment.EventStateID == ApprovedID || o.oSalesMan.oEmployment.EventStateID == PendingID) : 
                 o.oSalesMan.oEmployment.EventStateID == ApprovedID)
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };

查询基本上是说,从特定日期之前发生的所有销售事件中获取销售额和公司ID。销售活动的状态和销售员的就业状态应始终“获得批准”,或者如果指定,也可以“等待”。

正如您所看到的那样,有一个日期比较和几个整数比较。使用哪个整数比较是基于属性是否与某个枚举值匹配。

我对自己的优化方法有一些想法,但我想听听别人的想法,他们可能会更深入地了解LINQ如何在幕后翻译这个查询。

由于

2 个答案:

答案 0 :(得分:0)

在我看来,您最大的挑战是您在Linq语句中进行多项标准检查会花费大量时间。 如何在oEvents中创建一个新属性 - 说“IsEligable”并在其他变量的Set语句中设置它的值(比在Linq中不断重新查询每个变量要快得多)。

然后,当你到达代码的这一部分时,你可以将你的Linq更新为以下内容:

var lQuery = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate && o.IsEligable == True)
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };

......我猜这会加快执行速度,但只是想一想......

答案 1 :(得分:0)

这同样可以提高可读性,以便加快速度,但尝试一下:

var lQueryTemp = from o in oEvents
where (o.oSalesEvent != null && o.oSalesEvent.OccurDate < oCalcMgr.OccurDate)

if (oCalcMgr.InclTransTypes == Definitions.TransactionTypes.SalesAll)
{
  lQueryTemp = from o in lQueryTemp
        where (o.oSalesEvent.EventStateID == ApprovedID || o.oSalesEvent.EventStateID == PendingID) &&
      (o.oSalesMan.oEmployment.EventStateID == ApprovedID || o.oSalesMan.oEmployment.EventStateID == PendingID);
}
else
{
  lQueryTemp = from o in lQueryTemp
        where (o.oSalesEvent.EventStateID == ApprovedID &&  o.oSalesMan.oEmployment.EventStateID == ApprovedID);
}

var lQuery = from o in lQueryTemp
select new { SaleAmount = o.SaleAmount.GetValueOrDefault(), CompanyID = o.oSalesEvent.CompanyID };

这可以通过拉出oCalcMgr.InclTransTypes的两个检查来加快速度,这对于此查询来说实际上是一个常量。