EF:渴望包含单个字段
EF: Eagerly include single field
我的数据库中有一个 Object
,它有一个对象 Owner
。 Owner
有一个字符串 Name
。 Object
还持有对象 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)
.
时已经可以看到此行为
我的数据库中有一个 Object
,它有一个对象 Owner
。 Owner
有一个字符串 Name
。 Object
还持有对象 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)
.