2010-05-27 48 views
6

在實體框架(特別是EF 3.5,但如果它存在於EF 4中,它給了我一個升級的理由)是否可以延遲加載集合的一部分?我也可能接近這個錯誤,所以我願意接受建議。我的表/實體類似於此:懶惰加載實體框架EntityCollection與條件

Person   PersonMeal   Meal 
------ 1---* ---------- *---1 ----- 
ID    ID     ID 
...    PersonID    ... 
        MealID 
        Value 
        ... 

我已經通過實體框架通過存儲過程被檢索Person對象的列表。我有一種觀點,一次只顯示一個Meal,所以我只想要與該餐相關的信息。目前我的代碼如下所示:

Function GetPersons() As List(Of Person) 
    Dim personList = context.StoredProcedureCall(param1, param2, param3).ToList() 
    personList.ForEach(Function(x) LazyLoadProperties(x)) 
    Return personList 
End Function 

' Work around function because VB lambdas don't take Sub's 
Function LazyLoadProperties(ByVal person As Person) As Object 
    If (Not person.PersonMeal.IsLoaded) Then 
     person.PersonMeal.Load() 
    End If 
    Return Nothing 
End Function 

問題是這是加載整個集合。當然,這是一個小集合,所以最壞的情況下我可以加載它,然後刪除除我需要的一個之外的所有內容,但這並不理想。另外,我不確定是否可以在沒有觸發任何修改集合的事件的情況下進行,因爲它們本來不應該在那裏。

+0

「Person」與PersonMeal有多對多的關係,PersonMeal與'Meal'有多對多的關係,如問題所示?或者'Person'與'Meal'有一個多對多的關係,而'PersonMeal'則是連接表?如果是這樣,則不應該爲「PersonMeal」生成實體。不過,我也注意到了一個「價值」字段。你能否澄清你的數據結構? EDM的屏幕截圖可能會有所幫助,以及您的數據庫結構。 – Yakimych 2010-10-15 18:18:35

+0

@ Yakimych你說得對,它是人與餐之間的M2M,PersonMeal是連接表/實體。 – 2010-10-15 18:39:11

+0

@ Agent_9191 - 好的,在這種情況下,應該只有一個PersonEntity表,但沒有生成實體。 'Person'實體應該有'Meals'集合,'Meal'實體應該有'People'集合。您是從數據庫生成模型還是在設計器中自己創建模型?什麼是Value屬性(這可能是EF生成PersonMeal實體的原因)? – Yakimych 2010-10-15 19:47:21

回答

2

在這種情況下,而不是使用Load方法,你可以在數據庫中查詢數據:

Function GetPersons() As List(Of Person) 
    Dim personList = context.StoredProcedureCall(param1, param2, param3).ToList() 

    Dim person As Person 
    For Each person in personList 
     person.PersonMeals = From pm in context.PersonMeals.Include("Meal") 
          Where pm.Person.Id == person.Id And pm.Meal.Id == Meal_ID 
          Take 1 
    Next person 

    Return personList 
End Function 

我認爲person.PersonMeals是一個集合,否則,你可以使用FirstOrDefault而不是Take

在這個查詢中,我們基本上選擇了所有PersonMeals實體(與Meal一起),它們的人員ID是循環中的當前人員以及所需的膳食ID。如果您的數據庫沒有損壞的數據(具有相同PersonID-MealID組合的多行),則會有0或1個結果,這些結果將寫入您的PersonMeals屬性中。

+0

P.S .:對不起我的VB。 – Yakimych 2010-10-15 22:10:37

+0

並不像我期望的那樣優雅,但這是有效的。 – 2010-10-22 14:08:25

0

Yakimych的答案應該有效,但代碼有一些錯誤。

正確語法應該是:

Private Function GetPersons() As List(Of Person) 
    Dim personList As List(Of Person) = Context.StoredProcedureCall(param1, param2, param3).ToList() 
    For Each p In personList 
     Dim pId As Integer = p.Id 
     p.PersonMeals = (From pm As PersonMeal In context.PersonMeals.Include("Meal") 
         Where (pm.Person.Id = pId And pm.Meal.Id = Meal_ID) Take 1).ToList 
    Next 
    Return personList 
End Function 

我希望它能幫助。

1

你的問題很清楚:是否有可能懶洋洋地加載只有部分集合,答案是否定的!不在EF1或EF4中。順便說一句,如果最後一餐是主題,開始查詢!而不是檢索人和那裏用餐,檢索最後的膳食和附加的人。

+0

只是爲了澄清 - EF不提供延遲加載部分集合的開箱方法。延遲加載意味着'Meals'集合不會與'Person'一起加載,而是在加載'People'後的一段時間。但是,您可以通過查詢「膳食」來清楚地實現這一點。因此,我不會明白表示這是不可能的。 – Yakimych 2010-10-21 13:12:15

+0

爲什麼答案是否定的?我認爲英孚團隊不難解決這個問題。 – 2014-12-17 18:28:35