使用`groupjoin`的查询无法翻译,尽管它被证明是受支持的

我不明白为什么这不翻译。这似乎正是这里描述的用例。

LINQ 表达式

DbSet<A>()
    .GroupJoin(
        inner: DbSet<B>(),
        outerKeySelector: a => a.AId,
        innerKeySelector: b => b.AId,
        resultSelector: (a, bs) => new {
            a = a,
            bs = bs
         })
DbSet<A>()
    .GroupJoin(
        inner: DbSet<B>(),
        outerKeySelector: a => a.AId,
        innerKeySelector: b => b.AId,
        resultSelector: (a, bs) => new {
            a = a,
            bs = bs
         })

产生错误:

无法翻译。以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用,显式切换到客户端评估。有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038。

产生异常的 LINQ 代码是

编辑:也许我误解了文档,这是一个不翻译的例子。

执行类似于以下示例的查询会生成 Blog & IEnumerable 的结果。由于数据库(尤其是关系数据库)无法表示客户端对象的集合,因此 GroupJoin 在许多情况下不会转换为服务器。它要求您从服务器获取所有数据以在没有特殊选择器的情况下执行 GroupJoin(下面的第一个查询)。但是,如果选择器限制选择的数据,那么从服务器获取所有数据可能会导致性能问题(下面的第二个查询)。这就是 EF Core 不翻译 GroupJoin 的原因。

但后来我的问题变成了:如何在不需要导航属性的情况下实现我正在寻找的结果?

回答

链接文档中的解释只是遵循 EF Core 团队的愿景并且很荒谬,因为它当然可以轻松翻译 - 我在这里与团队进行了长时间的讨论Query with GroupBy 或 GroupJoin throws exception #17068并在此处继续Query: Support GroupJoin 当它是最终查询运算符 #19930 时,试图说服他们为什么应该支持它,无论参数如何都没有运气。

重点是(这就是当前的解决方法)它可以像相关子查询 ( SelectMany)一样被处理,它被正确地翻译和处理(即使查询结果形状没有 SQL 等效项。

无论如何,当前状态是“需要设计”(无论这意味着什么),解决方法是将连接替换为相关子查询(这是 EF Core 在查询转换期间“扩展”集合导航属性时在内部使用的)。

在你的情况下,更换

join b in ctx.Bs on a.aId equals b.aId into bs

let bs = ctx.Bs.Where(b => a.aId == b.aId)

但是,我强烈建议添加和使用导航属性。不知道为什么你“不能使用”它们,在不投影实体的 LINQ to Entities 中,它们只为关系提供元数据,从而自动生成必要的连接。通过不定义它们,您只会给自己带来不必要的限制(除了 EF Core 限制/错误之外)。一般来说,EF Core 在使用导航属性而不是手动连接时效果更好并支持更多功能。


以上是使用`groupjoin`的查询无法翻译,尽管它被证明是受支持的的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>