如何将带有 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.rev
和d2.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();
}
我有一个类似的 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.rev
和d2.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();
}