开发者

How to join using complex expression using Linq2Sql C# Expressions

I need to implement such query: In C# Linq2Sql Statements this can be written so:

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

But I wonder how to do this using C# Expressions. I mean something like this:

var query = Foo.Join(...).Select(...);

I see that Join method gives opportunity only to use equal join f1.Id == f2.Id. But how to write in C# expressions more complex query expressions, where is,开发者_JAVA技巧 for example, such expression as f1.Id < f2.Id?


While other answers will produce the same result, it doesn't translate to the same semantically to the original query syntax.

If you want something semantically closer to the original query syntax, you would use the SelectMany extension method, as that is what query syntax translates to when you have more than one from clause:

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);

Also, it should be noted that while you can use the Join method, you can only use it in situations where you want inner join semantics based on equality. Anything else and you have to use SelectMany with a call to Where.


There's no direct conversion since your original query isn't using a join...but I think this might get you close:

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);


If you rearrange your query, you might be able to stick with the expression syntax which is simple and readable. How about joining on the .Value property and filtering on f1.Id < f2.Id? That should provide the results you're looking for.

var query = from f1 in Foo
            join f2 in Foo on f1.Value equals f2.Value
            where f1.Id < f2.Id
            select f1;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜