EF核心查询Were子句是集合吗?

时间:2019-01-23 08:22:00

标签: c# entity-framework linq-to-sql entity-framework-core ef-core-2.2

我正在尝试在EF Core中建立一个合理的查询,该查询返回从事物集合派生的事物集合。基本上,在原始SQL中,可以执行JOIN。

它位于ASP.NET Core中,因此初始集合是SecurityPrincipal对象上的Roles列表:

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上的角色的所有组引用的所有资产。

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查询?

1 个答案:

答案 0 :(得分:3)

通常应避免在内存集合中的{em>上使用AnyContains以外的任何LINQ运算符,例如roles(根据代码,输入IEnumerable<string>)。

换句话说,代替

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

使用功能等效的

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

保证将后者转换为SQL IN,而不能将后者转换为SQL Contains

有趣的是,同时引起误解的是,EF Core试图变得聪明并以与Contains相同的方式翻译前者,并在执行包含查询时成功,但在用作其他查询的一部分时未成功

可以将其视为当前的EF Core实现缺陷。但是,解决方法/解决方案是(如开头所述)不依赖它,而始终使用get-pip.py