EF:如何进行有效的延迟加载(不是1 + N选择)?

时间:2010-10-22 12:54:11

标签: orm entity-framework-4 linq-to-entities

从实体列表开始并通过关联需要所有依赖实体,有没有办法使用相应的navigation-propertiy来加载所有具有一次db-round-trip的子实体? IE浏览器。通过导航属性生成一个WHERE fkId IN (...)语句?

更多详情
我找到了加载孩子的方法:

  1. 将父实体集保持为IQueriable< T>

    • 不好,因为db必须每次都找到主集并加入以获取所请求的数据。
  2. 将父对象放入数组或列表中,然后通过导航属性获取相关数据 var children = parentArray.Select(p => p.Children).Distinct()

    • 这很慢,因为它会为每个主要实体生成一个选择。
    • 创建重复的对象,因为每组子项都是独立创建的。
  3. 将主要实体中的外键放入数组中,然后过滤整个dependent-ObjectSet
    var foreignKeyIds = parentArray.Select(p => p.Id).ToArray();
    var children = Children.Where(d => foreignKeyIds.Contains(d.Id))

    Linq然后生成所需的“WHERE foreignKeyId IN(...)” - 子句。

    • 这很快但只能用于1:* - 关系,因为链接表被映射掉了。
    • 在所有
    • 之后使用Ids消除EF的可读性优势
    • EntityCollection类型的导航属性< T>没有填充
  4. 通过.Include() - 方法加载,包括完整性(要求延迟加载)

    • Alledged将所有包含在一起的东西加入并返回一个巨大的扁平结果。
    • 必须预先决定使用哪种数据
  5. 有一些方法可以通过3的性能获得2的简单性吗?

2 个答案:

答案 0 :(得分:0)

您可以将父对象附加到您的上下文,并在需要时获取子项。

foreach (T parent in parents) {
    _context.Attach(parent); 
} 
var children = parents.Select(p => p.Children);

编辑:用于附加多个,只需迭代。

答案 1 :(得分:0)

我认为找到一个好的答案是不可能的,或者至少不值得麻烦。相反,像Dapper这样的微型ORM可以消除在sql-columns和object-properties之间映射的需要,并且无需先创建模型。还可以简单地编写所需的sql,而不是理解要编写的linq要生成它。但IQueryable<T>将被遗漏。