如何使用Linq对同一张表执行LEFT JOIN筛选符合要求的记录
自关联表按自身或关联行条件筛选的Linq实现方案
假设有一张自关联表,行与行之间存在关联关系,我们需要筛选出满足特定条件的行,或者其关联行满足该条件的行。
为简化说明,参考如下原始表结构及数据:
| ID | Linked_ID | Active |
|---|---|---|
| 1 | null | 0 |
| 2 | 1 | 1 |
| 3 | null | 1 |
| 4 | 3 | 0 |
本次筛选规则为:获取所有自身Active值为1,或者其关联行的Active值为1的行。
对应的SQL实现语句如下:
SELECT t1.* FROM MyTable t1 LEFT JOIN MyTable t2 ON t1.Linked_ID = t2.ID WHERE t1.Active = 1 OR t2.Active = 1
预期返回结果如下:
| ID | Linked_ID | Active |
|---|---|---|
| 2 | 1 | 1 |
| 3 | null | 1 |
| 4 | 3 | 0 |
方法语法实现(优先推荐)
你原有写法调整后完整代码如下:
var result = dbSet .GroupJoin(dbSet, t1 => t1.Linked_ID, t2 => t2.ID, (t1, t2Group) => new { t1, LinkedRow = t2Group.FirstOrDefault() }) .Where(x => x.t1.Active == 1 || (x.LinkedRow != null && x.LinkedRow.Active == 1)) .Select(x => x.t1) .ToList();
说明:GroupJoin返回的t2Group是t1关联到的所有行,由于自关联场景下Linked_ID和ID是一对一关系,每组最多只会有一条匹配行,直接调用FirstOrDefault()即可拿到对应的关联行,和SQL左连接逻辑完全对应。
查询语法实现
和SQL逻辑对齐度更高的查询语法写法如下:
var result = (from t1 in dbSet join t2 in dbSet on t1.Linked_ID equals t2.ID into t2Group from t2 in t2Group.DefaultIfEmpty() where t1.Active == 1 || (t2 != null && t2.Active == 1) select t1).ToList();
两种写法最终返回的结果和上述预期完全一致。
内容的提问来源于stack exchange,提问作者Mielipuoli
相关产品推荐
相关产品推荐

