In the Where clause of a Linq statement, like this,
var myClasses = (from b in db.MyRecords
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
where (b.Active == 1)
select new { b });
The expression b.Active==1
works fine. But if I do this,
Expression<Func<MyRecords, bool>> filter = my => my.Active == 1;
[Update: Because of Hans' answer I have kept this as the original, but in reality, I mistyped here. The Expression is actually using the underlying type, not the EF generated plural like the query Linq. I actually have this,
Expression<Func<MyRecord, bool>> filter = my => my.Active == 1;
]
And try this,
var myClasses = (from b in db.MyRecords
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
where (filter)
select new { b });
The compiler complains,
Cannot convert query expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
I have seen lots of SO question with this, but I do not understand why it will not work. I am misunderstanding fundamental, so I'm not really asking anyone to write the code. I want to know what Linq wants so I have a better understanding of Linq, not just making something work. This works, for example,
var myClasses = (from b in db.MyRecords.Where(filter)
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
select new { b });
I want to know why it works there and not in the Where after the joins. If I do the Where at the end of the joins, the compiler is still aware of the MyRecords fields, including Active.
I think this is what I'm after for a proper description, as it seems to fit my probably pretty well.
Your filter is just of wrong type to be applied in the first example. The blue linq syntax does a lot of magic for you to make this query easy to read. What actually happens under the hood is creation of some anonymous types that contain references to your items. Note that in that where clause you can use
p
andcse
variables as well. And when you factor that to your expression you might figure it to be like thisExpression<Func<Tuple<MyRecords, People, Courses>>
in reality it will not be a tuple but some anonymous type.When you ask resharper to convert blue syntax to method chain it generates it like this:
And actually you cannot use the filter variable in the blue syntax like you did:
You would have to switch to method call:
now just because we trimmed the inner query to just
b
you can apply you filter.