2013-03-27 69 views
2

dbcontext api似乎將導航屬性設置爲ICollections(對於關聯的*端)。正常的方式來獲得可查詢的對象(如,如果你想要一個計數)似乎是默認情況下,如何讓數據庫中的實體框架導航屬性查詢過濾器?

int count = dbcontext.Entry(entry).Collection(c => c.navprop).Query().Count(); 

,但如果你想在DB經常篩選不方便。更重要的是,它也容易忘記。如果有人不小心說

int count = entry.navprop.Count(); 

那麼它得到的所有數據的服務器上,確實有計數,這是緩慢的。

對於ObjectContext默認使用的EntityCollection類型也是如此。

int count = entry.navprop.CreateSourceQuery().Count(); 

有沒有辦法在模型中設置或其他地方,對於一個導航屬性的默認集合類型爲IQueryable或的ObjectQuery或某種查詢類型的?

注意這僅僅是用於導航性能在上下文中的實際對象集和dbset項的問題似乎是可查詢的

回答

1

我想出瞭解決我的大部分問題的解決方案。我最終做的是使用ObjectContext API並在我的模型中創建需要很長時間訪問私有(用於獲取和設置)的導航屬性。您可以通過右鍵單擊nav屬性在edmx文件中執行此操作。

然後,我爲包含私有導航屬性的類創建了部分類文件,並在此行中添加了一些內容。

public ObjectQuery<NavPropType> NavPropName 
{ 
    get 
    { 
     if(privateNavProp != null) //in case lazy loading is disabled or something 
     return privateNavProp.CreateSourceQuery(); 
     else 
     return null; 
    } 
} 

現在沒有之類的用戶可能會意外地嘗試所有navprop項目的拉動,其中有很多。而且在nav導航上進行查詢也很容易,而不必每次都記得調用CreateSourceQuery。

我沒有添加setter,因爲該導航屬性只能在我的應用程序中讀取。我確信有一種方法可以適應這種模式,但我不太瞭解ObjectContext API來說明如何去做。

我只是最終這樣做的導航屬性,可能有大量的數據在他們身後,因爲留下其他的那些對性能沒有影響。

編輯:使其成爲私人,我碰到了後來的一個缺點是,我再也不能做

db.EntryTable.OrderBy(e => e.privateNavProp.Count()) 

即使它已經足夠聰明,不會讓所有的實體

+0

沒有人知道如果CreateSourceQuery足夠慢,它應該有一個私人成員的第一次調用getter時設置的私人成員,並在隨後的調用中使用,而不是每次調用CreateSourceQuery? – bdwain 2013-03-28 18:24:39

0

號IQueryable的是不是一個集合; IQueryable是一個接口,其實現評估針對數據源的查詢(集合將是數據源)。

當您加載實體對象,您可以裝載數,但是,如果內聯一些無關痛癢的方法調用是不是你的事:

from e in EntityA 
<optional where clause for entity> 
select new 
{ 
    Entity = e, 
    filteredNavPropCount = e.navprop.Where(np => <optional where clause for collection>).Count() 
} 
+0

它的不清楚我會在哪裏使用此代碼。 – bdwain 2013-03-27 07:08:01

+0

雖然我發現令人驚訝和惱人的是,調用導航屬性不會在數據庫中進行計數,但我更大的問題是人們會看到導航屬性中的調用計數,而不會想到更多,儘管他們從數據庫中提取額外的數據。 – bdwain 2013-03-27 07:11:05

+0

您可以在想要過濾導航屬性集合的位置使用它,或者以某種方式對其進行聚合,而無需從數據庫中檢索所有實體 - 正如您在問題中所述。 – Moho 2013-03-27 07:11:36