In Entity Framework (specifically EF 3.5, but if it exists in EF 4 it gives me a reason to upgrade) is it possible to lazy load only part of a collection? I may be approaching this wrong too, so I'm open to suggestions. My tables/entities look similar to this:
Person PersonMeal Meal
------ 1---* ---------- *---1 -----
ID ID ID
... PersonID ...
MealID
Value
...
I have a list of Person
objects that have been retrieved through Entity Framework via a stored procedure. I have a view that only shows one Meal
at a time, so I only want the information related to that meal. Currently I have code that looks like this:
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
The issue is this is loading up the entire collection. Granted it's a small collection so worst case scenario I can load it all up and then remove all but the one I need, but that is far from ideal. Plus I'm not sure if it would be possible without triggering any of the events of modifying the collection since they shouldn't have been in there in the first place.
In this case, instead of using the Load
method, you can just query the database for your data:
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
I assume that person.PersonMeals
is a collection, otherwise you can use FirstOrDefault
instead of Take
.
In this query we basically select all the PersonMeals
entities (together with the Meal
) that have the person ID as the current person in the loop and the meal ID you want. If your DB does not have corrupt data (multiple rows with the same PersonID-MealID combinations), there will be 0 or 1 results, which will be written into your PersonMeals
property.
Your question was pretty clear : is it possible to lazily load only part of a collection and the answer is no ! Not in EF1 nor in EF4. Btw, If the last meal is the subject, start querying by this ! Instead of retrieving the person and there meal, retrieve the last meals and the person attached to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With