【问题标题】:Lambda expression for outer joins外连接的 Lambda 表达式
【发布时间】:2014-06-11 20:29:44
【问题描述】:

我想为

写一个等价的 lambda
from col in db.Collectors
  join f in db.Files
on new { col.CollectorCode, col.StatusID }
  equals new { f.CollectorCode, StatusID = 1 } into f_join
from f in f_join.DefaultIfEmpty()
where
  col.FileID == null
orderby
  col.CollectorCode
select new {
  col.CollectorCode,
  col.Name
}

我有一个表格收集器和表格文件。表文件包含每个收集器的多个记录(文件),我只想检索表文件中没有记录的收集器。

我不清楚该怎么做。

这是我所拥有的,但没有按预期工作:

db.Collectors.Join(
                db.Files,
                col => col.CollectorCode,
                f => f.CollectorCode,
                (col, f) => new { Collector = col });

【问题讨论】:

    标签: c# sql linq lambda


    【解决方案1】:

    听起来像一个简单的Where 子句:

    db.Collectors.Where(c => !db.Files.Any(f => f.CollectorCode == c.CollectorCode));
    

    我在内部查询中使用Any,因此在找到匹配项时它会“短路”。可能有更有效的方法,但这会奏效。

    【讨论】:

    • 这不会导致左外连接,不。左外连接意味着左集中的每个项目(在本例中为收集器)在结果集中都有一条记录,如果右集中有多个匹配项(此处的文件),那么就有那么多结果集中的记录,对应于每个配对。这不会创建该结构。问题的重点是他有一个有效的查询(查询语法),只是想知道如何用方法语法编写它。
    • @Servy,我无法理解他的“加入”逻辑,所以我使用了以下语句:“我只想检索表文件中没有记录的收集器。”这对我来说听起来也不对,但我觉得这就是问题所在。由于我不知道正确的翻译,所以我编写了我从头开始编写时会使用的方法。我同意您的回答是问题的最佳翻译和“意图”(因此我赞成)。
    • @Servy 你可能是对的,但它按我的意愿工作!谢谢
    • @BradleyDotNET,没错,可能是我走错了路,谢谢你的回答。
    【解决方案2】:

    join ... into查询语法代码对应GroupJoin,而不是Join

    db.Collectors.GroupJoin(
        db.Files,
        col => col.CollectorCode,
        f => f.CollectorCode,
        (col, f_join) => new { col, f_join })
    

    第一个子句之后的任何from 子句都将对应于SelectMany

    db.Collectors.GroupJoin(...)
        .SelectMany(join => join.f_join.DefaultIfEmpty().Select(f => new{join.col, f}))
        //...
    

    就个人而言,像这样的查询需要传播从以前的操作“过去”投射的信息,另一个操作在查询语法中往往比方法语法更清晰,因为这里的方法语法需要不断地将所有内容投影出来包含所有要保存的数据的匿名类型。

    【讨论】:

      猜你喜欢
      • 2011-03-30
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      相关资源
      最近更新 更多