如何使用Linq2Sql C#表达式使用复杂表达式进行连接

时间:2011-01-19 19:13:37

标签: c# linq linq-query-syntax

我需要实现这样的查询:在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

3 个答案:

答案 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;