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

C# 如何使用Linq2Sql C表达式使用复杂表达式进行连接,c#,linq,linq-query-syntax,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; 我发现Join方法只提供了使用相等Join f1.Id==f2.Id的机会。但是如何在C表达式中编写更复杂的查询表达式,例如,其中是f1.Id

我需要实现这样的查询:在C Linq2Sql语句中,可以这样编写:

var query = from f1 in Foo
            from f2 in Foo
            where f1.Id < f2.Id && f1.Value == f2.Value
            select f1;

我发现Join方法只提供了使用相等Join f1.Id==f2.Id的机会。但是如何在C表达式中编写更复杂的查询表达式,例如,其中是f1.Id由于原始查询未使用联接,因此没有直接转换…但我认为这可能会让您接近:

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);
虽然将产生相同的结果,但它不会转换为与原始查询语法相同的语义

如果希望在语义上更接近原始查询语法,可以使用extension方法,因为当您有多个from子句时,查询语法就是这样翻译的:


另外,应该注意的是,虽然可以使用Join方法,但只能在需要基于相等的内部连接语义的情况下使用它。如果需要其他任何查询,则必须使用SelectMany调用Where。

如果重新排列查询,则可以使用简单易读的表达式语法。连接.Value属性并对f1.Id
var query = from f1 in Foo
            join f2 in Foo on f1.Value equals f2.Value
            where f1.Id < f2.Id
            select f1;

什么是c1和c2?并且您的联接没有on子句…很抱歉,它应该是f1。Value==f2。Value@Justin尼斯纳:有一个直接转换,选择许多和匿名类型。@casperOne-OP特别询问如何使用连接来实现他的目标…而不是其他运算符。@Justin Niessner:没有使用连接的特定请求,而是,有点像连接;我的注意力集中在C表达式上,我想他的意思是非查询语法版本。@casperOne-我猜这一切都取决于你如何解释这个问题。当你发布到StackOverflow时,更多的理由是要尽可能清楚@BothOfYou——根据OP中的查询,您不认为原始结构很可能有点误导吗?应该重写而不是仅仅翻译成方法语法吗?原始结构表明,询问者可能对连接不太熟悉。正如你们都知道的,20k+rep占了很大一部分,所以问题实际上只是问了一个错误的问题,不是吗?
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);
var query = from f1 in Foo
            join f2 in Foo on f1.Value equals f2.Value
            where f1.Id < f2.Id
            select f1;