This query can be broken (exactly this, not your real query that is much more complex :-) )
IQueryable<atype> query = a;
IQueryable<btype> query2 = from a1 in query
join join b1 in b on a1.id1 equals b1.id1
select b1;
IQueryable<ctype> query3 = from b1 in query2
join join c1 in c on b1.id1 equals c1.id1
select c1;
Each of these can be put in a method that has a signature like:
IQueryable<ctype> JoinQuery2(IQueryable<btype> query2)
{
IQueryable<ctype> query3 = from b1 in query2
join join c1 in c on b1.id1 equals c1.id1
select c1;
return query3;
}
This type of query can be easily broken because after each join you discard the "old" type (so in at the end of query2
you only have select b1
, not select a1+b1
). If you had to keep both objects, it wouldn't be doable, because you would need new { a1, b1 }
that is an anonymous object, that can't be passed around because it's an anonymous object.
Note that perhaps simply splitting the query in multiple variables will solve your NPR problem, because the analyzer won't see the full chain of methods.
var query2 = from a1 in a
join join b1 in b on a1.id1 equals b1.id1
select b1;
var query3 = from b1 in query2
join join c1 in c on b1.id1 equals c1.id1
select c1;
In this case you can even use anonymous objects, like
var query1 = from a1 in a
join join b1 in b on a1.id1 equals b1.id1
select new { a1, b1 };
var query3 = from a1b1 in query2
join join c1 in c on a1b1.b1.id1 equals c1.id1
select new { a1b1.a1, a1b1.b1, c1 };
and so on.