Linq与子查询和LET的性能

时间:2014-02-20 06:15:34

标签: c# sql linq entity-framework linqpad

我在LinqPad中执行了一个查询(针对SQL2010后端的EF4),它使用导航属性来访问相关表。我实际上无法访问索引等等,并且想知道是否有任何方法可以避免查询底部的“firstordefault”项中固有的所有子查询。我尝试在顶部使用'let'语句,如“let accounts = i.ExpenseItemAccountings.FirstOrDefault()”然后使用该引用使其仅运行一个子查询,但它仍然需要一个多小时才能完成对任何有意义数量的记录运行此查询。

我有什么方法可以提高效率吗?

    var output = from i in ExpenseItems where
i.Er_Approved_Date >= fromDate &&
i.Er_Approved_Date <= toDate
select new {ER_Num = i.ErNum,
         Line_Num = i.ItemNum,
         Report_Title = i.Report_Title,
         Requestor = i.Requester_Name,
         Preparer = i.Preparer_Name,
         ER_Total_Value = i.Er_TotalVal,
         Partition = i.Org,
         Transaction_Date = i.Item_Transaction_Date,
         Approved_Date = i.Er_Approved_Date,
         Item_Amount = i.Item_Amount,
         Tips = i.Item_Tips,
         GST = i.Item_Gst,
         Have_Receipt = i.Item_Have_ReceiptTf,
         Have_Invoice = i.Item_Have_InvoiceTf,
         Vendor = i.Item_Vendor,
         City = i.Item_City,
         Item_Expense_Type = i.Item_Expense_Type,
         Item_Description = i.Item_Expense_Description,
         Misc_Item_Commodity = i.Item_Misc_Commodity_Name,
         Misc_Item_SubCategory = i.Item_Misc_Specify,
         Misc_Item_OtherMisc_Description = i.Item_Misc_Specify_Other_Desc,
         Entity_Num = i.ExpenseItemAccountings.FirstOrDefault().Item_Entity_Num,
         Entity_Name = i.ExpenseItemAccountings.FirstOrDefault().Item_Entity_Name,
         Account_Num = i.ExpenseItemAccountings.FirstOrDefault().Item_Account_Num,
         Account_Desc = i.ExpenseItemAccountings.FirstOrDefault().Item_Account_Name,
         SubAccount_Num = i.ExpenseItemAccountings.FirstOrDefault().Item_SubAccount_Num,
         SubAccount_Name = i.ExpenseItemAccountings.FirstOrDefault().Item_SubAccount_Name,
         CostCentre_Num = i.ExpenseItemAccountings.FirstOrDefault().Item_CostCentre_Num,
         CostCentre_Name = i.ExpenseItemAccountings.FirstOrDefault().Item_CostCentre_Name,
         Project_Code = i.ExpenseItemAccountings.FirstOrDefault().Expense_Item_ProjectCode,
         ////Percent_Allocated = i.ExpenseItemAccountings.FirstOrDefault().Item_Percent,
         ER_Comments = i.Er_Comments,
         Item_First_Comment = i.ExpenseItemComments.FirstOrDefault().Comment_Content,
         Violations = i.ExpenseItemViolations.Count()
                      };

1 个答案:

答案 0 :(得分:2)

在LinqPad上,您应该能够查看从LINQ语句生成的SQL语句。

在我看来,在LINQ to Entities(或LINQ to SQL)中使用let或导航属性之间始终存在争议。有时一个简单的JOIN也可能更好。换句话说,这完全取决于您的LINQ提供程序(实体框架)如何将您的特定查询优化为SQL语句。

我建议您使用所有let/join/navigation测试查询,以查看生成的SQL语句。

如果您没有SQL profiler或intellitrace工具,可以在代码中ObjectQuery下使用System.Data.Objects查看实时SQL语句:

((ObjectQuery)anyLinqQuery).ToTraceString();

您也可以尝试使用多个from子句:

var output = from i in ExpenseItems
             from exp in i.ExpenseItemAccountings
             where ....
             select new {...};

var output = from i in ExpenseItems
             from exp in i.ExpenseItemAccountings.DefaultIfEmpty()
             where ....
             select new {...};