LINQ Join 与 On 子句中的多个条件
Posted
技术标签:
【中文标题】LINQ Join 与 On 子句中的多个条件【英文标题】:LINQ Join with Multiple Conditions in On Clause 【发布时间】:2011-12-01 15:48:36 【问题描述】:我正在尝试在 LINQ 中实现一个查询,该查询在 ON 子句中使用带有多个条件的左外连接。
我将使用以下两个表的示例Project (ProjectID, ProjectName) 和Task (TaskID, ProjectID, TaskName, Completed)。我想查看所有项目及其各自任务的完整列表,但只查看那些已完成的任务。
我不能对Completed == true
使用过滤器,因为这会过滤掉任何没有完成任务的项目。相反,我想将Completed == true
添加到连接的 ON 子句中,以便显示完整的项目列表,但只显示已完成的任务。没有完成任务的项目将显示单行,其中 Task 的值为空。
这是查询的基础。
from t1 in Projects
join t2 in Tasks
on new t1.ProjectID equals new t2.ProjectID into j1
from j2 in j1.DefaultIfEmpty()
select new t1.ProjectName, t2.TaskName
如何在 on 子句中添加&& t2.Completed == true
?
我似乎找不到任何关于如何执行此操作的 LINQ 文档。
【问题讨论】:
相关答案here使用Lambda语法 【参考方案1】:您只需要将匿名属性在两边命名相同
on new t1.ProjectID, SecondProperty = true equals
new t2.ProjectID, SecondProperty = t2.Completed into j1
基于@svick 的 cmets,下面是另一个可能更有意义的实现:
from t1 in Projects
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true)
.DefaultIfEmpty()
select new t1.ProjectName, t2.TaskName
【讨论】:
这似乎是一种不明显的方法。我不确定我会理解它应该做什么。 @svick - 使用匿名类型允许您加入多个条件。您只需要确保两种类型的属性名称都匹配。不确定混乱来自哪里? 令人困惑的是,它确实更有意义,因为and
加入了两个等式,而不是某个“奇怪”对象的一个等式。为了证明我的观点,您的代码是错误的。要让它工作,你必须在左边有true
,在右边有t2.Complete
。
谢谢阿杜奇。我不得不在查询中交换双方以获取正确的上下文,但这有效。这个问题被简化了,在我的现实世界问题中,不只是 SecondProperty 是真还是假,SecondProperty 是一个整数,我使用AND SecondProperty IN (123, 456)
。我将继续迎接这一挑战,我们将不胜感激您提供的任何帮助。
@svick - 很好,我切换了 t2.Completed 和 true 值的顺序。我添加了另一个对您来说可能不那么奇怪的解决方案。【参考方案2】:
给你:
from b in _dbContext.Burden
join bl in _dbContext.BurdenLookups on
new Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID equals
new Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID
【讨论】:
这看起来更容易理解。【参考方案3】:你不能那样做。 join
子句(和Join()
扩展方法)仅支持等值连接。这也是为什么它使用equals
而不是==
的原因。即使你可以做这样的事情,它也行不通,因为join
是一个内连接,而不是外连接。
【讨论】:
未请求外部连接,并且(请参阅其他答案),显然您可以。以上是关于LINQ Join 与 On 子句中的多个条件的主要内容,如果未能解决你的问题,请参考以下文章
`INNER JOIN` 过滤条件在查询中的位置; `ON` 或 `WHERE` 子句 [关闭]
为啥以及何时在 WHERE 子句中带有条件的 LEFT JOIN 不等于在 ON 中的相同 LEFT JOIN? [复制]