含多OR条件的多表左连接LINQ方法语法实现问题及方案
复杂条件左连接的LINQ方法语法实现
我之前查阅了大量相关解答但未找到有效解决方法,常规思路里OR条件通常放在Where子句而非连接本身,但这个查询场景显然不适用这种方式。
表结构说明
先给出简化后的两张表定义:
Claim: FKeyID int, CKeyID int, ICode varchar(100), IName varchar(100) Lookup: LFKeyID int, LCKeyID int, LICode varchar(100), LIName varchar(100)
目标SQL
需要用LINQ方法语法实现的左连接SQL如下:
select * from Claim c left join Lookup l on (l.LFKeyID = c.FKeyID OR l.LFKeyID = 0) AND (l.LCKeyID = c.CKeyID OR l.LCKeyID = 0) AND (l.LICode = c.ICode OR l.LIName = c.IName)
之前的尝试(未满足需求)
我曾尝试以下代码,但仅实现了初始键连接,未包含Lookup键为0的OR条件,陷入了困境:
query = _context.Claim.Join(_context.Lookup, clm => clm.FKeyID, lk => lk.LFKeyID, (clm, lk) => new { ... fields go here ... }) .DefaultIfEmpty().ToList();
可行解决方案
经过反复测试,找到了能实现需求的写法,分享给有相同需求的开发者:
var query = _context.Claim.Where(i => (various initial filter criteria)) .SelectMany(clm => _context.Lookup, (clm, lk) => new { clm, lk }) .Where(combined => (combined.lk.LFKeyID == combined.clm.FKeyID || combined.lk.LFKeyID == 0) && (combined.lk.LCKeyID == combined.clm.CKeyID || combined.lk.LCKeyID == 0) && (combined.lk.LICode == combined.clm.ICode || combined.lk.LIName == combined.clm.IName)) .DefaultIfEmpty() .Select(s => new { // 在这里列出需要的字段,比如: ClaimFKeyID = s.clm.FKeyID, LookupLIName = s.lk?.LIName }).ToList();
这里用SelectMany先将两张表做笛卡尔积,再通过Where子句筛选出符合复杂连接条件的记录,最后用DefaultIfEmpty()来模拟左连接的效果,确保即使没有匹配的Lookup记录,Claim的记录也会被保留。
内容的提问来源于stack exchange,提问作者nonesuch
相关产品推荐
相关产品推荐

