Как присоединиться, используя сложное выражение, используя выражения Linq2Sql C # - PullRequest
2 голосов
/ 19 января 2011

Мне нужно реализовать такой запрос: в C # Linq2Sql Statements это можно записать так:

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 ]

1 голос
/ 19 января 2011

Хотя 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.

1 голос
/ 19 января 2011

Прямого преобразования нет, поскольку ваш исходный запрос не использует объединение ... но я думаю, что это может приблизить вас:

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);
0 голосов
/ 19 января 2011

Если вы измените порядок запроса, вы сможете придерживаться синтаксиса выражения , который прост и удобен для чтения .Как насчет присоединения к свойству .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;
...