C# LINQ Join返回重复结果 如何获取包含关联列表的单条记录
LINQ一对多关联去重方案
问题根因
你当前使用的普通内连接写法会在一对多关联场景下产生笛卡尔乘积,当单条Model记录关联N条B表记录、M条C表记录时,最终会返回N*M条重复的Model记录,属于关联查询的正常行为,该需求完全可以通过LINQ实现。
修正后的LINQ查询语法写法
使用分组连接join ... into替代普通内连接,直接获取当前Model对应的所有B、C表记录集合,不会产生笛卡尔乘积:
var result = (from model in this.GetDefaultQuery() // 关联A表(默认Model和A为1对1关系,如为1对多可同样用into分组) join a in _context.A on model.ModelId equals a.ModelId // 分组关联B表,拿到当前Model对应的全部B记录 join b in _context.B on model.ModelId equals b.ModelId into bCollection // 分组关联C表,拿到当前Model对应的全部C记录 join c in _context.C on model.ModelId equals c.ModelId into cCollection // 过滤条件提前,减少查询数据量 where model.ModelId == modelId select new { M = model, A = a, // 提取B表的名称列表 BNameList = bCollection.Select(b => b.Name).ToList(), // 提取C表去重后的名称列表 DistinctCNameList = cCollection.Select(c => c.Name).Distinct().ToList() }) // 按主键过滤后最多只有一条Model记录,直接取结果即可 .FirstOrDefault();
EF/EF Core环境推荐写法
如果是基于EF/EF Core的ORM查询,提前在Model实体中配置好导航属性后,不需要手动编写关联逻辑,代码更简洁:
// Model实体配置示例 public class Model { public int ModelId { get; set; } public string Name { get; set; } // 导航属性:关联A对象 public A A { get; set; } // 导航属性:关联B表集合 public List<B> Bs { get; set; } // 导航属性:关联C表集合 public List<C> Cs { get; set; } } // 查询代码 var result = _context.Models .Include(m => m.A) .Include(m => m.Bs) .Include(m => m.Cs) .FirstOrDefault(m => m.ModelId == modelId); // 按需提取字段即可 var bNameList = result.Bs.Select(b => b.Name).ToList(); var distinctCNameList = result.Cs.Select(c => c.Name).Distinct().ToList();
上述写法同样兼容LINQ to Object场景。
内容的提问来源于stack exchange,提问作者user10860402
相关产品推荐
相关产品推荐

