Allow filtering for Include extension method
There is no ablity to filter included objects in ObjectQuery<TSource>.Include method.
Allow filter predicate in Include method in Entity Framework.
I suppose this method of ObjectQuery<TSource> may have following signature:
/// <summary>
/// Includes related objects which meet to predicate
/// </summary>
/// <typeparam name="TRelation">Type of related object on another end of navigation property</typeparam>
/// <param name="relationSelector">Expression that returns set of related objects</param>
/// <param name="predicate">Predicate that has to be met</param>
/// <returns>Query</returns>
public System.Data.Objects.ObjectQuery<TSource> Include<TRelation>(Expression<Func<TSource, IEnumerable<TRelation>>> relationSelector, Expression<Func<TRelation, bool>> predicate);
16 comments
-
Mike
commented
You may be able to workaround this by flipping around your query for Linq to Entities, then flipping it back with Linq to Objects. Using the example above:
var q = context.Products.Where(p => p.UnitPrice > 20 & p.Category.StartsWith("a")).Include(p => p.Category);
var r = q.ToList().Select(p => p.Category).Distinct();
Note: This would not work if you are expecting Categories that don't have products in your results.
-
AdminDiego Vega
(Admin, DataFx)
commented
I have moved this idea from WCF Data Services to Entity Framework as it seems to refer to EF.
-
craig
commented
The suggestions below indicate that this can be with EF4. These comments are not correct, as the relationship depends specifically on change tracking. This can be illustrated as follows.
var p = ParentTable.AsNoTracking().Select(o => new { Parent = o, Children = o.Children.Where(_ => _.Name.Length == "child")}).AsEnumerable().Select (_p => _p.Parent);
does not work.
var p = ParentTable.Select(o => new { Parent = o, Children = o.Children.Where(_ => _.Name.Length == "child")}).AsEnumerable().Select (_p => _p.Parent);
Appears to work because a subset of the children happen to be change tracked.
-
Paul
commented
This is something we really need. I have looked at some the alternatives mentioned below and as other comments have explained they are not adequate solutions.
-
Dominik
commented
Hi again,
I think maybe I don't expressed myself very well. What I really need is to get those paged Categories having only products with UnitPrice greater than 20.
-
Dominik
commented
I need to perform something like this:
context.Categories.Where(ca = ca.StartsWith("a")).Include(ca => ca.Products.Where(p => p.UnitPrice > 20));
-
Tec Goblin commented
-
Piers
commented
Dan, the applying of filters mentioned in that post is when explicitly loading entities, not when Eagerly loading entities which is what Include would give.
Moderator... this is the same suggestion as http://data.uservoice.com/forums/72025-ado-net-entity-framework-ef-feature-suggestions/suggestions/1015345-allow-filtering-for-include-extension-method?ref=title so the scores should be added together!
-
Piers
commented
Matthieu, your solution works if you know what you want to include at compile time... however the great thing about Include() is that it can be added to a query dynamically (e.g. within an if statement). Using a Projection means you lose that flexibility... doubly annoying as the introduction of a Projection also strips off any existing Include()s on the main query!!!
-
Jake
commented
Agreed, this doesn't solve the problem. This particular issue is a deal-breaker for our company and we'll have to switch back to LLBLGen Pro until this gets added to the framework.
-
Dan Meierotto commented
I am not sure if you have see this, but this is possible now: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx
See: Applying filters when explicitly loading related entities
-
PK
commented
OOO! i'd love to use Generics instead of strings anyday :) :) +1 +1 +1
-
Adrian Hesketh
commented
How about having a generic include, e.g. .Include<Users>().Include<Roles>() instead of passing a string too.
Or something like Include<User>(u => u.Role) to include the role of a user instead of User.Include(Role).
-
PK
commented
@Matthieu - that's not acceptable. That's using a projection, which is not the same thing. We need to have predicates available to the Include .. so you can Filter, Take(x), Skip, etc...
By your suggestion/blog post, it's an anonymous projection with properties. That's doesn't mean we can get right poco's with their aggregations filled appropriately. Imaging asking (aka. Including) all the audit history for _each_ user retrieved? instead of just the most recent 10? or the the most recent 11-20 audit records for each user.. u get the drift.
-
Matthieu MEZIL commented
Hi Mike
You can do it with EF4 even if it is less simple than the method you propose.
I wrote a post on it http://msmvps.com/blogs/matthieu/archive/2009/10/07/ef-include-with-where-clause.aspx