2014-02-20 54 views
1

我有一個查詢我在LinqPad(EF4針對SQL2010後端)執行,它使用導航屬性訪問相關的表。我真的沒有辦法擺弄索引等等,並想知道是否有任何方法可以避免那些'firstordefault'項目中固有的所有子查詢朝向查詢底部。我試着在「let accounts = i.ExpenseItemAccountings.FirstOrDefault()」中使用頂部的'let'語句,然後使用該引用使其僅運行一個子查詢,但仍需要一個多小時才能完成針對任何有意義數量的記錄運行此查詢。Linq性能與子查詢和LET

有什麼辦法可以讓這個效率更高?

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() 
         }; 
+0

這種類型的q的uery不適合Linq,你可能需要使用類似Row_Number的東西直接執行TSQL命令。 – sgmoore

回答

1

在LinqPad上,您應該能夠查看由LINQ語句生成的SQL語句。

在我看來,在LINQ to Entities(或LINQ to SQL)中使用let或導航屬性總是存在爭議。有時候簡單的JOIN也可能會更好。換句話說,這一切都取決於您的LINQ提供程序(實體框架)如何將您的特定查詢優化爲SQL語句。

我建議你測試你的查詢與所有let/join/navigation查看生成的SQL語句。

您可以使用System.Data.ObjectsObjectQuery在你的代碼的情況下,你沒有SQL事件探查器或智能跟蹤工具來查看實時的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 {...}; 
+0

這是一個很大的缺點,它返回ALL ExpenseItemAccountings而不是每個ExpenseItem的第一個ExpenseItemAccountings。 – sgmoore

+0

非常感謝你們 – Glinkot