渴望加载实体框架核心

Posted

技术标签:

【中文标题】渴望加载实体框架核心【英文标题】:Eager loading Entity framework core 【发布时间】:2017-07-01 14:24:33 【问题描述】:

我正在寻找在创建条目后加载导航属性的最优雅/最佳方式。

情况是这样的: *我在我的表中创建一行并按 ID 链接其他 2 个表。我得到的对象只包含 id,而不是实际的链接对象。 *通过急切加载我想加载这些对象

context.Entry(b)
    .Reference(e => e.Table1)
    .Reference(e => e.Table2)
    .Load();

似乎不起作用,我无法链接引用,所以我可以查询完整的对象:

context
    .Objects
    .Where(o => o.ID == id)
    .Include(o => o.Table1)
    .Include(o => Table2)
    .FirstOrDefault();

或者这样做:

context.Entry(b)
    .Reference(e => e.Table1)
    .Load();

context.Entry(b)
    .Reference(e => e.Table2)
    .Load();

但这会创建(我怀疑)2 次对数据库的调用,而不是 1 次组合调用。还是我错过了链接这些引用的另一种方式?

【问题讨论】:

【参考方案1】:

对于这个特定场景,您可以使用简单的匿名类型投影并依赖导航属性修复,如Loading Related Data 中所述:

提示 Entity Framework Core 将自动修复先前加载到上下文实例中的任何其他实体的导航属性。因此,即使您没有明确包含导航属性的数据,如果之前加载了部分或所有相关实体,该属性仍可能会被填充。

所以以下内容可以完成这项工作:

context.Objects
    .Where(o => o.ID == id)
    .Select(o => new  o.Table1, o.Table2 )
    .Load();

理论上应该更好(应该只加载相关数据)。但是,由于当前的 (v1.1.0) EF Core 错误,它还将包括所有根对象字段,因此使其等同于带有 Includes 的变体:

context.Objects
    .Where(o => o.ID == id)
    .Include(o => o.Table1)
    .Include(o => o.Table2)
    .Load();

我个人会使用第一种方法,因为这些错误有望在未来的 EF Core 版本中得到修复,而第二种方法的行为是“设计使然”。

【讨论】:

以上是关于渴望加载实体框架核心的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:渴望加载特定的列

Spring Jpa 规范和渴望加载

带有参数的渴望加载 - laravel

Laravel 4:渴望加载

Laravel Eloquent:渴望加载多个嵌套关系

渴望使用实例变量加载自定义联接