2

我需要实现这样的查询:在 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 方法只提供了使用 equal join 的机会f1.Id == f2.Id。但是如何在 C# 表达式中编写更复杂的查询表达式,例如 ? 等表达式在f1.Id < f2.Id哪里?

4

3 回答 3

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);
于 2011-01-19T19:26:54.140 回答
1

虽然其他 答案会产生相同的结果,但它不会在语义上转换为与原始查询语法相同的结果。

如果您想要在语义上更接近原始查询语法的内容,您将使用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.

于 2011-01-19T19:37:26.773 回答
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;
于 2011-01-19T19:41:39.907 回答