LINQ多列内连接查询时GroupJoin类型推断错误如何解决
问题原因
- LINQ的
join子句仅支持等值匹配,不支持or这类非等值关联逻辑,你需要的单字段匹配两个目标字段的场景不能用默认的equals关联实现。 - 你代码中join两侧的匿名类属性名不匹配:左侧匿名类属性为
SentFromEmployeeId、SentToEmployeeId,右侧为Id1、Id2,C#要求参与equals比较的匿名类必须属性名、类型、顺序完全一致才会被识别为同一类型,直接触发类型推断失败报错。 - 你使用
into j生成的是分组集合类型IGrouping,不能直接访问j.DepartmentId,属于语法错误。
解决方案
根据你的业务需求,可选两种实现方式:
方式1:非等值关联(完全匹配你给出的SQL逻辑)
用双from子句实现带or条件的inner join,避免使用join语法的等值限制:
var startDate = new DateTimeOffset(new DateTime(2021,11,1)); var endDate = new DateTimeOffset(new DateTime(2021,11,16)); var query = from l in context.LeaveUpdateLogs join lr in context.LeaveRequest on l.LeaveRequestId equals lr.Id from e in context.Employee where e.Id == lr.SentFromEmployeeId || e.Id == lr.SentToEmployeeId where l.RequestedDate >= startDate && l.RequestedDate < endDate where e.DepartmentId == 100 select new { lr.SentFromEmployeeId, lr.SentToEmployeeId, LeaveUpdateLog = l, RelatedEmployee = e };
注意:如果同一条请假申请的发送人和接收人都属于部门100,该写法会返回2条重复的日志记录。
方式2:双次关联Employee(无重复数据,性能更优)
如果你的实际需求是只要发送人或接收人任意一个属于部门100就匹配,可分别关联两次Employee,逻辑更清晰也不会产生重复数据:
var startDate = new DateTimeOffset(new DateTime(2021,11,1)); var endDate = new DateTimeOffset(new DateTime(2021,11,16)); var query = from l in context.LeaveUpdateLogs join lr in context.LeaveRequest on l.LeaveRequestId equals lr.Id join eFrom in context.Employee on lr.SentFromEmployeeId equals eFrom.Id join eTo in context.Employee on lr.SentToEmployeeId equals eTo.Id where l.RequestedDate >= startDate && l.RequestedDate < endDate where eFrom.DepartmentId == 100 || eTo.DepartmentId == 100 select new { lr.SentFromEmployeeId, lr.SentToEmployeeId, LeaveUpdateLog = l, SendFromEmployee = eFrom, SendToEmployee = eTo };
该写法生成的SQL会对应你给出的关联e1、e2两个Employee别名的逻辑,更符合常规业务使用场景。
内容的提问来源于stack exchange,提问作者I Love Stackoverflow
相关产品推荐
相关产品推荐

