How can we improve Entity Framework Core?

Eager loading for properties of derived classes

In entity framework there should be a way to eager load (include) navigation properties of a derived class.

When in an data model for entity framework has a navigation property it is not posseble to eager load that navigation property besides when using OfType<> or when eager loading the derived type itself by a navigation property.
This could be done by using a special syntax of the include path.
Since a property of the base class can not have the same name as the derived class, it would also be possible to navigate to the derived class by its name.

e.g.: If class Derived inherits from Base and has a navigation property named Prop one could say
dbContext.BaseSet.Include("Derived.Prop")

this should query all entities of type Base and eager load property Prop for all instances of Derived in the reslult list

319 votes
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)

    We’ll send you updates on this idea

    Christof Nordiek shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    22 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • James S. commented  ·   ·  Flag as inappropriate

        It's 2017. Unbelievable that this critical feature was never addressed. It's impossible to use table per hierarchies in any reasonable way here except to put all navigation collections on the base type. If the property is on a derived type only, then the following shit show entail:

        1. You CANNOT use "Include" to load the shit in the original query, because syntax like Include(x => (x as DervivedType).Collection) doesn't work.
        2. So you're forced to make individual calls to 'Load' for each entity to load the derived type's collections one at a time, because loading all children in a collective query doesn't properly associate them with the entities in the context.

        Normally, if I load an object without include, then later load it's children, EF will automatically populate the objects navigation property. When the navigation property is on a derived type, it fails to do so, leaving the collection empty. If you try to populate the collection and save, it throws an error. You actually have to get the entity entry in the context for each instance of the derived type and load it manually with Load. Insane.

      • Ciaran Colgan commented  ·   ·  Flag as inappropriate

        Not a solution but a workaround. Use a Select projection on your IQueryable, with the derived type accessed by: "DerivedTypeDto = (x as DerivedType)"

      • b commented  ·   ·  Flag as inappropriate

        Eager loading of N:1 makes sense. What is not acceptable is to have 5-10 related properties, doing 5-10 round trips to the database because you can't get this all in a single trip. This although has to be configurable (for some N:1 relations you might not want this).

        Also defining eager load of some 1:N relations (when you know there won't be more than 10-50 items per aggregate) does make a sense. It's still better than the N+1 select issue from lazy-loading.

        EF7 1.1 - still behind NH2.x (released at 2008) or NH3.0(2010)...

        If there would be a real open-source competition, EF7 would have the same fate as of Unity.

      • Anonymous commented  ·   ·  Flag as inappropriate

        i have barely used entity and this is enough to stop be dead in my tracks.

        once again i drop entity to a shinny pamphlet

      • Leroy commented  ·   ·  Flag as inappropriate

        I was quite impressed by the whole inheritance support in EF, only to find out weeks later that it's a half baked solution.

        This was reported in 2010.. how can this still not be implemented yet?

      • Levi Hobbs commented  ·   ·  Flag as inappropriate

        This is absolutely ridiculous. I guess no one in the world uses inheritance. It's a totally new thing.

      • Eric commented  ·   ·  Flag as inappropriate

        Hmmm 386 votes and this moves from "under review" to "no status". I certainly hope this becomes a priority at some point. The current solution is terribly inefficient.

      • Ran Davidovitz commented  ·   ·  Flag as inappropriate

        This is a must in real life scenarios (not the simple demos). today i was forced to remove inheritance!!

      • Hitesh commented  ·   ·  Flag as inappropriate

        It should also support navigation properties of navigation property
        For example, Orders -> OrderDetails -> Items

        ElectronicItem derives from Items
        ElectrionicItem -> MoreDetails

        Hence, it will be

        Orders -> OrderDetails -> ElectronicItem (Items) -> MoreDetails

        Now, I want to retrieve Order including all navigation properties

        e.g.
        context.Orders.Include("OrderDetails").Include("OrderDetails.Items").Include("OrderDetails.Items.MoreDetails");

      • M. Holmgren commented  ·   ·  Flag as inappropriate

        No, eager loads should be explicit.

        However, there should be support for including sub type property navigation includes which today forces multiple queries

      • M. Holmgren commented  ·   ·  Flag as inappropriate

        Context.CreateObjectSet<BaseType>.Where(o => o ...).Include("BasetypeNavigationProperty").Include<Subtype1>("SubTypeNavigationProperty").Include<Subtype2>("OtherSubtype2Property")

        This is what I want in an eager load query

      • Francis Ouellet commented  ·   ·  Flag as inappropriate

        If I have this :
        Invoice 1 -- * Amounts
        Amounts -> UnitTax or Fee

        I want to load invoice and his dependances

        IQueryable<Invoice> query = from f in context.Set<Invoice>()
        .Include("Amounts")
        .Include(f => (f.Amounts as UnitTax).UnitTaxDetail)
        .Include(f => (f.Amounts as Fee).FeeDetail)
        where f.ID.Equals(id)
        select f;

        Not working!

      • Bruno de Souza Melo commented  ·   ·  Flag as inappropriate

        Solution.

        The derived type it's applied only for Conceptual Data Model (Entity Data Model). Remove any foreignkey of your derived physical table.

        Ex.:

        Car - IDCar, Name

        SportCar - IDCar, WheelsType

        Remove the foreignkey (don't remove the column just relationship for using on Mapping Detail) of SportCar and set BaseType to Car in Entity Data Model.

        See the article association with derived types.

        http://msdn.microsoft.com/en-us/library/dd163157.aspx

        Thank you.

      • Bruno de Souza Melo commented  ·   ·  Flag as inappropriate

        Solution.

        The derived type it's applied only for Conceptual Data Model (Entity Data Model). Remove any foreignkey of your derived physical table.

        Ex.:

        Car - IDCar, Name

        SportCar - IDCar, WheelsType

        Remove the foreignkey (don't remove the column just relationship for using on Mapping Detail) of SportCar and set BaseType to Car only in Entity Data Model.

        See the article association with derived types.

        http://msdn.microsoft.com/en-us/library/dd163157.aspx

        Thank you.

      • Bruno de Souza Melo commented  ·   ·  Flag as inappropriate

        Very useful!!

        I agree it would be nice to have a way to eager load on a navigation property in a derived type. Here is some tentative syntax for it with lambda expressions:

        var peopleAndManagers1 =
        from p in context.People.Include(p => (p as Employee).Manager)
        where p.LastName.StartsWith("a")
        select p;

        Or alternatively:

        var peopleAndManagers2 =
        from p in context.People.Include<Employee>(e => e.Manager)
        where p.LastName.StartsWith("a")
        select p;

      ← Previous 1

      Feedback and Knowledge Base