I am using Entity Framework 4.3.1 with a Code First approach. Also, I am using LinqKit so as to use the PredicateBuilder.
If I have tables like so:
Location,
After about a week's worth of struggling, I found out that you can in fact do this. The steps are:
subPredicate
)Invoke
that subPredicate
from within another Predicate (predicate
), against the property of the parent object.Expand
your predicate
when using it in your Where
clause.Here's the revised code for your example:
var subPredicate = PredicateBuilder.True<TimeZone>();
subPredicate = subPredicate.And(tz => tz.TimeZoneCode == "EST");
var predicate = PredicateBuilder.True<Location>();
predicate = predicate.And(l => subPredicate.Invoke(l.TimeZone));
List<Location> locations = context.Locations
.AsExpandable().Where(pred.Expand())
.Select(loc => loc).ToList();
Just to update this: it turns out that the intent of these kinds of predicates is to filter the primary entity. The mental concept is: decide which entities you would like to return, and return them. EF is apparently not designed for this kind of deep predicate application on child entities.
One person (I don't remember where) made a great point: If the children were pre-loaded, you would not expect a partially-loaded collection. Thus, it would not make sense to have an Invoice entity, for example, but only half of the Invoice Lines.
What I wanted to achieve was more along the lines of EXISTS() or IN(), where you could say "Give me all Invoices where there are Invoice Lines for Product Types 'Nuts' and 'Bolts'". This is feasible, but you may have to apply LINQ or compose your own object. The intent of EF out of the box is to hand you the Invoice, and then you may lazily or eagerly load the Invoice Lines, but not using them as a filter straight from the database.
There are some constructs that I saw to accomplish something close, but the syntax gets very unmanageable very quickly.
Don't fight city hall.