[英]LINQ performing multiple queries instead of a single “joined” query
無論如何我不是LINQ高級用戶,但可以在基本級別上摸索。 我有一個關於LINQ如何制定它的查詢“策略”的問題。 我將嘗試盡可能地解釋這一點,並通過記憶寫出一個非常愚蠢的例子。
我有一個包含多個數據庫視圖的數據模型。 假設視圖的列結構如下:
PersonView
PersonViewId | Surname | GivenName | OtherViewId
------------------------------------------------
其他視圖
OtherViewId | PersonViewId | Name
---------------------------------
在設置視圖的主鍵(PersonView.PersonViewId / OtherView.OtherViewId)並將相應的字段設置為非nulable之后,我在PersonView.PersonViewId(Parent)與OtherView.PersonViewId(Child)之間創建了一個關聯。 我將它設置為“一對一”並編寫一些代碼來使用它:
StringBuilder s = new StringBuilder();
foreach(PersonView p in dc.PersonViews)
{
s.AppendLine(p.OtherViews.Name + "<br />");
}
在注意到性能極差之后,我對數據庫進行了分析,發現它正在對foreach語句中的每個PersonView進行查詢。
此時,我重新編寫了查詢,並在DBML中將關聯替換為LINQ查詢中的JOIN,對數據庫進行了分析,並按預期查詢了數據庫,僅查詢一次。
我認為這與某些事情有關,然后實際上正在查詢數據庫,但我不確定在哪里進行調試。 有人能指出我正確的方向,以幫助我提高使用協會的表現,還是我堅持使用JOIN來完成我需要的東西?
謝謝 :)
這是由延遲加載引起的 - 你可以通過應用LoadWith()
(相當於Linq到SQL的EF的Include()
)然后再進行查詢來解決這個問題:
var dlo = new DataLoadOptions();
dlo.LoadWith<PersonView>(p => p.OtherViews);
dc.LoadOptions = dlo;
//your query here
這是LINQ-2-SQL的延遲加載(也稱為延遲加載)功能,當你執行p.OtherViews.Name
它正在對OtherViews
表進行查詢。
有幾種方法可以解決它,一種是關閉延遲加載:
dc.DeferredLoadingEnabled = false;
另一種方法是在結果中投射您想要的所有內容,並使用投影:
var people = from p in dc.PersonViews
select new {
Person = p,
Name = p.OtherViews.Name
};
然后是BrokenGlass的建議,直到現在我都不知道:-)
你看到這個的原因是Linq對這些關系使用延遲加載。 換句話說,在您真正嘗試使用它之前,Linq不會加載關聯。
這可以幫助提高性能,因為如果您不總是需要關聯,則不會執行不必要的JOIN,也不會檢索不需要的數據。
如果您確定需要數據,它會影響性能,並且它會繼續發出請求。
您可以通過保持關聯原樣來解決這個問題,但請使用DataLoadOptions。 例如:
var dc = new DataContext();
dc.DeferredLoadingEnabled = false;
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<PersonView>(o => o.OtherView);
dc.LoadOptions = loadoptions;
現在,無論何時查詢PersonView,它都會自動加載OtherView關系。
這種方法的好處是你可以在需要時打開和關閉它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.