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;
精彩评论