Entity Framework Core 2.0:如何将多结果对象合并为单一集合
解决方案:直接返回扁平的TargetObject序列
当然可以搞定!咱们直接调整LINQ查询的结构,把所有分散在不同关联表中的TargetObject实例直接合并成一个扁平的序列,完全不需要在内存里手动遍历那些匿名对象。
改写后的查询代码
var result = await dbContext.Table1DbSet .Where(t1e => t1e.Id == id && t1e.Id2 == id2) // 展开Table1关联的所有Table2集合,逐个处理每个Table2实体 .SelectMany(t1e => t1e.Table2NavPropICollection) // 对每个Table2,合并所有TargetObject来源为单个序列 .SelectMany(t2e => // 把单个TargetObject转为单元素序列,再依次拼接三个枚举集合 new[] { t2e.Table3NavPropObject.TargetObject } .Concat(t2e.Table3NavPropObject.Table4NavPropObject.Table5NavPropICollection.Select(t5e => t5e.TargetObject)) .Concat(t2e.Table3NavPropObject.Table6NavPropObject.Table7NavPropICollection.Select(t7e => t7e.TargetObject)) .Concat(t2e.Table3NavPropObject.Table8NavPropICollection.SelectMany(t8e => t8e.Table9NavPropICollection.Select(t9e => t9e.TargetObject))) ) .ToListAsync();
逻辑说明
- 第一层
SelectMany:把原查询中Table1对应的嵌套Table2集合展开,让我们能直接操作每个Table2实体,而不是嵌套的集合结构。 - 第二层
SelectMany:针对每个Table2实体,我们把所有TargetObject的来源合并成一个连续序列:- 用
new[] { ... }将单个的singleObject包装成单元素数组,这样就能和其他枚举集合用Concat方法拼接。 - 依次拼接
enumerable1、enumerable2、enumerable3(注意enumerable3本身已经是SelectMany展开后的结果,直接复用即可)。
- 用
- 最终结果:整个查询会被EF Core翻译成对应的SQL,直接从数据库拉取所有符合条件的
TargetObject实例,返回一个扁平的List<TargetObject>。
可选优化:去重
如果你的场景中可能出现重复的TargetObject实例,想要去重的话,可以在最后添加去重逻辑:
// 按ID去重(假设TargetObject有Id属性) .DistinctBy(to => to.Id) .ToListAsync();
内容的提问来源于stack exchange,提问作者monty
相关产品推荐
相关产品推荐

