簡體   English   中英

LINQ執行多個查詢而不是單個“加入”查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM