ChatGPT解决这个技术问题 Extra ChatGPT

LINQ Join 与 On 子句中的多个条件

我正在尝试在 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 }

如何将 && t2.Completed == true 添加到 on 子句?

我似乎找不到任何关于如何执行此操作的 LINQ 文档。

使用 Lambda 语法的相关答案 here

V
Vikrant

您只需要在双方都将匿名属性命名为相同

on new { t1.ProjectID, SecondProperty = true } equals 
   new { t2.ProjectID, SecondProperty = t2.Completed } into j1

根据@svick 的评论,这是另一个可能更有意义的实现:

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)。我将继续迎接这一挑战,您可以提供的任何帮助将不胜感激。
@Kuyenda - 看看我的第二个解决方案:您可以将 x.Completed == true 更改为 listOfIntergers.Contains(x.Completed)
N
Nalan Madheswaran

在这里你去:

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 }

这看起来更容易理解。
s
svick

你不能那样做。 join 子句(和 Join() 扩展方法)仅支持等值连接。这也是为什么它使用 equals 而不是 == 的原因。即使你可以做这样的事情,它也行不通,因为 join 是一个内连接,而不是外连接。


没有要求外部联接,并且(请参阅其他答案),显然您可以。