gpt4 book ai didi

c# - EF Core 查询 Where 子句是一个集合?

转载 作者:太空狗 更新时间:2023-10-30 01:12:55 26 4
gpt4 key购买 nike

我正在尝试在 EF Core 中构建一个合理的查询,该查询返回一组事物,而这些事物又是从一组事物中派生出来的。基本上在原始 SQL 中,我们会执行 JOIN。

它在 ASP.NET Core 中,因此初始集合是 SecurityPrincipal 对象上的角色列表:

var roles = User.FindAll(ClaimTypes.Role).Select(r=>r.Value);

然后这些角色被映射到我们数据库中的组,因此我可以查找它们:

var groupsQuery = dbContext.Groups.Where(g=>roles.Any(r=>r==g.GroupName));
var groups = await groupsQuery.ToListAsync();

这个查询非常愉快,并按预期返回了一组组。然而,这些组可以访问另一个资源,这是我真正想要的,因为它是多对多的关系,所以有一个桥接表。

这是我尝试查询 AssetGroup 连接表,以便我可以获得映射到 SecurityPrincipal 上的角色的所有组引用的所有 Assets 。

var assetGroupsQuery = dbContext.AssetsGroups.Where(ag => groupsQuery.Any(ag => ag.Id == a.GroupId));
var assetGroups = await assetGroupsQuery.ToListAsync();

当我执行第二个查询时,我在输出窗口中收到大量垃圾邮件:

  The LINQ expression 'where ([ag].Id == [ag].GroupId)' could not be translated and will be evaluated locally.
The LINQ expression 'Any()' could not be translated and will be evaluated locally.
The LINQ expression 'where {from Group g in __groups_0 where ([ag].Id == [ag].GroupId) select [ag] => Any()}' could not be translated and will be evaluated locally.
The LINQ expression 'where ([ag].Id == [ag].GroupId)' could not be translated and will be evaluated locally.
The LINQ expression 'Any()' could not be translated and will be evaluated locally.

关于应该如何表达嵌套查询的任何线索,以便 EF Core 可以正确地组成单个 SQL 查询?

最佳答案

通常避免使用 AnyContains 以外的任何 LINQ 运算符在内存集合中 就像你的roles (根据代码应为 IEnumerable<string> 类型)。

换句话说,而不是

.Where(g => roles.Any(r => r == g.GroupName))

使用功能等同的

.Where(g => roles.Contains(g.GroupName))

后者保证被翻译成SQL IN ,而前者不是。

有趣且同时具有误导性的是,EF Core 试图变得聪明,并以与 Contains 相同的方式翻译前者。 , 并在执行包含查询时成功,但在用作另一个查询的一部分时不成功。

它可以被视为当前的 EF Core 实现缺陷。但解决方法/解决方案(如开头所述)不依赖它并始终使用 Contains .

关于c# - EF Core 查询 Where 子句是一个集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54322785/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com