Entity Framework "Self-casting Include" 技巧在 .NET 5/6 中不再有效
Entity Framework "Self-casting Include" trick no longer works in .NET 5/6
发现这个 Entity Framework Core 3.1 技巧的那天我非常高兴:
private static IIncludableQueryable<Widget, Widget> WidgetQueryIncludeFringles(IQueryable<Widget> widQuery)
{
return widQuery
.Include(w => w.Fringles).ThenInclude(f => f.Bauble)
.Include(w => w);
}
为什么?因为 Widget
有一堆导航属性,我想根据情况“包含”它们的任意组合。通过像上面这样的可组合查询,我避免了组合爆炸。
但是这些方法中的每一个都必须具有通用的 return 类型。 “w => w”这个技巧是救命稻草;我找不到任何其他方法将查询转换为所需的 return 类型。生活很美好,直到我尝试从 EF 3.1 转换为 EF 6.0。
现在我在 运行 时间得到这个异常:
System.InvalidOperationException: 'The expression 'w' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'
我知道 EF 5 具有用于过滤 Includes
的新功能,我猜测异常是实现这些功能的结果。有什么方法可以调整上述方法(不更改签名),以便它在 EF 5/6 下编译和 运行?
IIncludableQueryable
的第二个泛型类型参数的全部目的是允许链接 ThenInclude
。因此 IIncludableQueryable<T, T>
没有意义,因为它唯一允许的(如果支持的话)是 ThenInclude(T x => x.{Something})
.
但请注意 IIncludableQueryable<T, P>
正在继承(即 是一个 )IQueryable<T>
,这足以继续链接其他 Include
初始实体类型 T
(“路径”重置为开头)。
因此删除不必要的(现在不受支持的)技巧并更改 return 类型可以实现相同的目标,例如
private static IQueryable<Widget> WidgetQueryIncludeFringles(IQueryable<Widget> widQuery)
{
return widQuery
.Include(w => w.Fringles).ThenInclude(f => f.Bauble);
}
然后
IQueryable<Widget> query = ...;
query = WidgetQueryIncludeFringles(query)
.Include(w => w.SecondNavigation)
.Include(w => w.ThirdNavigation);
发现这个 Entity Framework Core 3.1 技巧的那天我非常高兴:
private static IIncludableQueryable<Widget, Widget> WidgetQueryIncludeFringles(IQueryable<Widget> widQuery)
{
return widQuery
.Include(w => w.Fringles).ThenInclude(f => f.Bauble)
.Include(w => w);
}
为什么?因为 Widget
有一堆导航属性,我想根据情况“包含”它们的任意组合。通过像上面这样的可组合查询,我避免了组合爆炸。
但是这些方法中的每一个都必须具有通用的 return 类型。 “w => w”这个技巧是救命稻草;我找不到任何其他方法将查询转换为所需的 return 类型。生活很美好,直到我尝试从 EF 3.1 转换为 EF 6.0。
现在我在 运行 时间得到这个异常:
System.InvalidOperationException: 'The expression 'w' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'
我知道 EF 5 具有用于过滤 Includes
的新功能,我猜测异常是实现这些功能的结果。有什么方法可以调整上述方法(不更改签名),以便它在 EF 5/6 下编译和 运行?
IIncludableQueryable
的第二个泛型类型参数的全部目的是允许链接 ThenInclude
。因此 IIncludableQueryable<T, T>
没有意义,因为它唯一允许的(如果支持的话)是 ThenInclude(T x => x.{Something})
.
但请注意 IIncludableQueryable<T, P>
正在继承(即 是一个 )IQueryable<T>
,这足以继续链接其他 Include
初始实体类型 T
(“路径”重置为开头)。
因此删除不必要的(现在不受支持的)技巧并更改 return 类型可以实现相同的目标,例如
private static IQueryable<Widget> WidgetQueryIncludeFringles(IQueryable<Widget> widQuery)
{
return widQuery
.Include(w => w.Fringles).ThenInclude(f => f.Bauble);
}
然后
IQueryable<Widget> query = ...;
query = WidgetQueryIncludeFringles(query)
.Include(w => w.SecondNavigation)
.Include(w => w.ThirdNavigation);