假设我有多个db表,为了方便起见,我将它们表示为列表:
EntitySource {
public int Id {get; set;}
public ICollection<Entity_1> table_1 { get; set }
public ICollection<Entity_2> table_2 { get; set }
public ICollection<Entity_3> table_3 { get; set }
}
Entity_1/Entity_2/Entity_3 {
public int Id { get; set; }
public string Name { get; set; }
}
List<Entity_1> table1 = new List<Entity_1>() {new Entity_1{Id = 1, Name = "First"}, new Entity_1{Id = 2, Name = "Second"}
List<Entity_2> table2 = new List<Entity_2>() {new Entity_2{Id = 3, Name = "First"}, new Entity_2{Id = 4, Name = "Second"}
List<Entity_3> table3 = new List<Entity_3>() {new Entity_3{Id = 5, Name = "First"}, new Entity_3{Id = 6, Name = "Second"}
我正在查询EntitySource,它包含对多个集合的引用,我想查询这些集合并Map到MergedList类,MergedList类包含两个属性,实体源的Id和一个包含EntitySource的所有合并集合的集合。
我想实现的是只对id进行查询,并将它们Map到单个整数列表。
就像这样:
var entities = await entitySource.Queryable()
.Select(e => new MergedList()
{
PrincipalId = e.Id,
CombinedIds = e.table1.Select(e => e.Id)
.Concat(e.table2.Select(e => e.Id)
.Concat(e.table3.Select(e => e.Id)
})
.ToListAsync(cancellationToken);
public class MergedList {
public int PrincipalId {get;set;}
public IEnumerable<int> CombinedIds {get;set;}
}
但是显然上面的语句是不起作用的,表达式无法解析。
无法转换投影中的集合子查询,因为父查询或子查询未投影唯一标识它并在客户端正确生成结果所需的必要信息。
使用Entity Framework Core v6.0
2条答案
按热度按时间k5hmc34c1#
您可以在客户端将它们组合起来。
ccrfmcuu2#
鉴于您的班级:
如果你只需要唯一的值,最简单的方法可能是联合。
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.union?view=net-8.0
使用我的DbContext代码如下:
生成的SQL看起来像这样:
如果出于某种原因实际上需要重复,您也可以这样做:
我用我的DbContext测试了这个:
这是用预期结果生成的查询:
这样使用Concat:
或者像这样:
会导致EF Core 7出现如下异常:
System.InvalidOperationException:'无法转换投影中的集合子查询,因为父查询或子查询未投影唯一标识集合子查询并在客户端正确生成结果所需的必要信息。尝试关联无键实体类型时可能会发生这种情况。对于“Distinct”之前的某些投影情况或“GroupBy”情况下的分组键的某些形状,也可能发生这种情况。这些属性应该包含操作所应用的实体的所有键属性,或者只包含简单的属性访问表达式。
即使你尝试投影列表的可能性也很高,你最终会得到这样的
Concat
:查看此帖子以获取更多信息:
https://github.com/dotnet/efcore/issues/26703#issuecomment-981843751