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);