EF:渴望包含单个字段

EF: Eagerly include single field

我的数据库中有一个 Object,它有一个对象 OwnerOwner 有一个字符串 NameObject 还持有对象 Details.

我需要 Object,它是 Details,还有 Owner.Name。我想阻止加载整个 Owner 对象(详述 here)并且我只需要一个数据库查询。

我试过了:

DataContext.Objects.Select(o => new { Object = o, OwnerName= o.Owner.Name })
           .Include(o => o.Object.Details);

但它抛出:

System.InvalidOperationException: 'The result type of the query is neither an EntityType nor a CollectionType with an entity element type. An Include path can only be specified for a query with one of these result types.

还尝试在 Select 之前调用 Include:

var d = DataContext.Objects.Include(o => o.Details)
.Select(o => new { Object = o, OwnerName= o.Owner.Name });

但这忽略了 Include,即。访问 d.Details 会导致数据库查询。

有什么想法吗?

应该 这样做(尽管 Details 加载在单独的 属性 中以更正@Flatter 的评论):

DataContext.Objects
           .Include(o => o.Owner>)
           .Include(o => o.Details)
           .Select(o => new {Object = o, 
                             OwnerName = o.Owner.Name,
                             Details = o.Details});

它 returns 一个新的 object,其中 Object 设置为选定的 Object(如果可以,请考虑重命名,这非常混乱),以及一个 OwnerName 从所有者 table 填充而不加载整个所有者。它还将 Details 作为单独的 属性 填充,因为 Select 忽略了 Include

我说它 "should" 有效,因为没有看到你的 table 结构,我不得不根据你对事物如何连接的描述进行猜测。

您所涉及的问题确实存在于 EF 中。

问题在于EF如何处理数据的加载。它加载对象的所有标量属性,但不加载导航属性。

Include 通过告诉 EF 包含指定的导航 属性(及其所有标量属性)[=18= 来影响此行为]

但是我们到了 Select。当您使用它时,您实际上是在提供一个 fixed 要检索的列列表。这会覆盖加载所有标量属性的默认行为,遗憾的是它也会覆盖您添加的 Include 语句。


最简单的解决方案是明确告诉 EF 检索详细信息:

var d = DataContext.Objects.Include(o => o.Details)
    .Select(o => new { 
               Object = o, 
               ObjectDetails = o.Details,
               OwnerName= o.Owner.Name 
    });

顺便说一句,由于 Select 明确说明了 EF 需要检索哪些列,因此您不再需要 Include 语句。

您在检索 o.Owner.Name 而无需实际调用 Include(o => o.Owner).

时已经可以看到此行为