我需要实现这样的查询:在C#Linq2Sql语句中,这可以写成:
var query = from f1 in Foo
from f2 in Foo
where f1.Id < f2.Id && f1.Value == f2.Value
select f1;
但我想知道如何使用C#表达式来做到这一点。我的意思是这样的:
var query = Foo.Join(...).Select(...);
我看到Join方法只提供使用相等连接f1.Id == f2.Id
的机会。但是如何在C#表达式中编写更复杂的查询表达式,例如,表达式为f1.Id < f2.Id
?
答案 0 :(得分:1)
由于您的原始查询未使用加入,因此没有直接转换...但我认为这可能会让您接近:
var query = Foo.Join(Foo,
f1 => f1.Value,
f2 => f2.Value,
(f1, f2) => new { f1, f2 })
.Where(g => g.f1.Id < g.f2.Id)
.Select(g => g.f1);
答案 1 :(得分:1)
虽然other answers会产生相同的结果,但它不会在语义上转换为原始查询语法。
如果您希望在语义上更接近原始查询语法,则可以使用SelectMany
扩展方法,因为当您有多个from
子句时,查询语法将转换为:
var query = Foo.
// from f1 in Foo
// from f2 in Foo
//
// Need the anonymous type to carry over the two items
// in the sequences, the compiler will do the same
// in your original query, although the names
// will be much more mangled.
SelectMany(f => Foo, (f1, f2) => new { f1, f2 }).
// f1.Id < f2.Id && f1.Value == f2.Value
Where(f => f.f1.Id < f.f2.Id && f.f1.Value == f.f2.Value).
// select f1;
Select(f => f.f1);
此外,应该注意的是,虽然您可以使用Join
方法,但您可以 在需要基于相等性的内部联接语义的情况下使用它。还有其他任何内容,您必须使用SelectMany
来调用Where
。
答案 2 :(得分:0)
如果重新排列查询,您可能会坚持使用简单易读的表达式语法。如何加入.Value
属性并过滤f1.Id < f2.Id
?这应该提供您正在寻找的结果。
var query = from f1 in Foo
join f2 in Foo on f1.Value equals f2.Value
where f1.Id < f2.Id
select f1;