Search code examples
entity-frameworkinheritanceeager-loadingnavigation-properties

How to include an inherited property in an "uneven" inheritance with Entity Framework?


I have the following model (simplified):

abstract class CartItem { EntityReference<Cart> Cart; }
class HotelCartItem : CartItem { EntityReference<Hotel> Hotel; }
class TransferCartItem : CartItem { }
class Hotel { }

As expressed "graphically":

CartItem
|<- HotelCartItem
|   |-> Hotel
|
|<- TransferCartItem

Now I want to load all CartItems and include data from the Hotel class if the type of CartItem is a HotelCartItem.

This is how I'm trying to do it, but it fails with a "does not declare a navigation property with the name 'Hotel'."

var q = from cartitems in context.CartItems
            .Include("Hotel")
        where cartitems.CART_ID == CartID
        select cartitems;

If I leave out the .Include("Hotel") the Hotel property of CartItems of type Hotel is null.

My question:
Is there a way to get around this?


Solution

  • I ended up splitting the query into several parts:

    1. Load the parent item, a "Cart".
    2. For each of the different types I got (HotelCartItem and TransferCartItem) I queried the db for a set of only that type:
    private IQueryable<T> GetCartItemQuery<T>(Guid CartID) where T : CartItem
    {
        if (typeof(T) == typeof(HotelCartItem))
        {
            var q = from ci in db.CartItems.OfType<T>()
                        .Include("Hotel")
                    where ci.CART_ID == CartID
                    select ci;
            return q;
        }
        else
        {
            var q = from ci in db.CartItems.OfType<T>()
                    where ci.CART_ID == CartID
                    select ci;
            return q;
        }
    }
    

    Call it with:

    var hotels = GetCartItemQuery<HotelCartItem>(CartID);
    var transfers = GetCartItemQuery<TransferCartItem>(CartID);
    

    3 . Add the CartItems to the collection of the Cart-object.