EF Core与ASP.NET Core WebAPI两表关联查询去重问题求助
问题根源分析
你当前的LINQ查询用了内连接,但FormControls和OtherFields对同一个FormId都是一对多的关系,直接join会产生笛卡尔积——每条FormControls记录都会和所有OtherFields记录配对,导致OtherFields跟着重复出现。而Distinct()无效的原因是:每个FormControls+OtherFields的组合都是唯一的,系统识别不到重复。
解决方案
根据你的需求,提供几种可行的处理方式:
方案1:分别查询再组装(推荐,逻辑清晰,避免笛卡尔积)
如果你的目标是获取指定FormId下的所有FormControls和所有不重复的OtherFields,建议直接分开查询两个表的数据,再组装成合理的DTO结构:
首先调整你的DTO设计(更符合一对多的业务逻辑):
public class FormFullDataDto { public List<FormControls> FormControlsList { get; set; } public List<OtherFields> OtherFieldsList { get; set; } }
然后编写查询代码:
// 查询指定FormId的所有FormControls var controls = await _context.FormControls .Where(c => c.FormId == request.FormId) .ToListAsync(); // 查询指定FormId的所有不重复OtherFields var otherFields = await _context.OtherFields .Where(f => f.FormID == request.FormId) .Distinct() // 仅当数据库中本身存在重复OtherFields记录时需要,否则可省略 .ToListAsync(); // 组装结果 var result = new FormFullDataDto { FormControlsList = controls, OtherFieldsList = otherFields };
方案2:保留原DTO结构的分组查询
如果你必须保留原FormControlsDto的结构(每个FormControls对应关联的OtherFields),可以用分组来避免重复:
var formControls = await _context.FormControls .Where(d => d.FormId == request.FormId) .Select(d => new FormControlsDto { FormControls = d, // 为每个FormControls单独查询对应FormId的所有OtherFields OtherFields = _context.OtherFields .Where(f => f.FormID == request.FormId) .Distinct() .ToList() }) .ToListAsync();
补充:确保Distinct()生效的前提
如果数据库中确实存在重复的OtherFields记录,需要让Distinct()能识别重复对象:在OtherFields实体类中重写Equals和GetHashCode方法,基于唯一标识字段判断重复:
public class OtherFields { // 你的实体字段... public int FormID { get; set; } public int Id { get; set; } // 假设Id是唯一主键 public override bool Equals(object obj) { if (obj is not OtherFields other) return false; // 根据唯一标识字段判断是否为同一对象 return FormID == other.FormID && Id == other.Id; } public override int GetHashCode() { return HashCode.Combine(FormID, Id); } }
内容的提问来源于stack exchange,提问作者Towseef Ahmed
相关产品推荐
相关产品推荐

