延迟加载带有条件的实体框架EntityCollection

时间:2010-05-27 18:01:52

标签: vb.net entity-framework lazy-loading

在Entity Framework中(特别是EF 3.5,但如果它存在于EF 4中,它给我一个升级的理由)是否可以延迟加载只是集合的一部分?我也可能接近这个错误,所以我愿意接受建议。我的表/实体看起来与此类似:

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

我有一个Person对象列表,这些对象是通过存储过程通过Entity Framework检索的。我有一个视图,一次只显示一个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

问题是这会加载整个集合。虽然它是一个小集合,所以最糟糕的情况我可以加载它然后删除所有我需要的,但这远非理想。另外,我不确定是否有可能在没有触发任何修改集合的事件的情况下,因为它们本来就不应该在那里。

3 个答案:

答案 0 :(得分: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属性。

答案 1 :(得分:1)

您的问题非常清楚:是否可以懒惰仅加载部分收藏品,答案是否定的!不在EF1或EF4中。顺便说一句,如果最后一餐是主题,请开始查询!而不是检索人和那里的饭菜,检索最后的饭菜和附在其上的人。

答案 2 :(得分: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

我希望它有所帮助。