【问题标题】:LINQ Join with Multiple Conditions in On ClauseLINQ Join 与 On 子句中的多个条件
【发布时间】: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语法

标签: linq join


【解决方案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.Completedtrue 值的顺序。我添加了另一个对您来说可能不那么奇怪的解决方案。
【解决方案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 是一个内连接,而不是外连接。

【讨论】:

  • 未请求外部连接,并且(请参阅其他答案),显然您可以。
猜你喜欢
  • 2021-11-21
  • 2014-02-07
  • 2017-04-07
  • 1970-01-01
  • 2015-07-07
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
相关资源
最近更新 更多