如何将带有 LEFT OUTER JOIN 的高级 SQL 语句转换为 LINQ?

How to translate an advanced SQL statement with LEFT OUTER JOIN to LINQ?

我有一个类似的 SQL 语句,如图 in this example 所示。对于以下table

CREATE TABLE [docs] (
  [id] int NOT NULL,
  [rev] int NOT NULL,
  [content] varchar(200) NOT NULL,
  PRIMARY KEY ([id],[rev])
) ;

及以下数据

INSERT INTO [docs] ([id], [rev], [content]) VALUES
  (1, 1, 'The earth is flat'),
  (2, 1, 'One hundred angels can dance on the head of a pin'),
  (1, 2, 'The earth is flat and rests on a bull``s horn'),
  (1, 3, 'The earth is like a ball.');

SQL 语句

SELECT d1.*
    FROM docs AS d1
    LEFT OUTER JOIN docs AS d2
    ON (d1.id = d2.id AND d1.rev < d2.rev)
    WHERE d2.id is null
    ORDER BY id;

仅显示每个 id:

具有最大 rev 值的行
id  rev content
1   3   The earth is like a ball.
2   1   One hundred angels can dance on the head of a pin

我的问题: 如何将此语句转换为 LINQ-to-SQL?在我看来,问题是 ON 子句中的 AND<

我尝试应用@NetMage 的方法,但我卡在了 < 条件下:

   using (MyDataContext context = new MyDataContext())
    {
        var query =
            from d1 in context.docs
            join d2 in context.docs on d1.id equals d2.id into jrv
            from x in jrv.Where(x => /* ??? */).DefaultIfEmpty()
            where x equals null
            select x;
        return query.ToArray();
    }

中的lambda表达式应该是d1.revd2.rev之间的比较。我该怎么做?

一般来说,最好将 SQL LEFT JOIN...WHERE ... = null 翻译成 EXISTS,在 LINQ 中是 Any:

var ans = from d1 in docs
          join d2 in docs on d1.id equals d2.id into d2j
          where !d2j.Any(d2 => d1.rev < d2.rev)
          orderby d1.id
          select d1;

但是,当然,您可以将其转换为显式 LINQ 空测试:

using (MyDataContext context = new MyDataContext()) {
    var query =
        from d1 in context.docs
        join d2 in context.docs on d1.id equals d2.id into d2j
        from d2 in d2j.Where(d2_2 => d1.rev < d2_2.rev).DefaultIfEmpty()
        where d2 == null
        select d1;
    return query.ToArray();
}