Entity framework 如何将继承财产包括在;“不均匀”;实体框架继承?

Entity framework 如何将继承财产包括在;“不均匀”;实体框架继承?,entity-framework,inheritance,eager-loading,navigation-properties,Entity Framework,Inheritance,Eager Loading,Navigation Properties,我有以下模型(简化): 如果我省略了.Include(“Hotel”)类型为Hotel的CartItems的酒店属性为空 我的问题: 有没有办法解决这个问题?在子类上急切地加载导航属性是很棘手的。除了单独加载外,我没有找到其他方法。简单的方法是在ObjectContext上注册自定义ObjectMaterialized处理程序(仅在EF 4.0中): context.ObjectMaterialized += RegisterEagerLoadingStrategies; 处理程序方法如下所示

我有以下模型(简化):

如果我省略了
.Include(“Hotel”)
类型为Hotel的CartItems的酒店属性为空

我的问题:

有没有办法解决这个问题?

在子类上急切地加载导航属性是很棘手的。除了单独加载外,我没有找到其他方法。简单的方法是在ObjectContext上注册自定义ObjectMaterialized处理程序(仅在EF 4.0中):

context.ObjectMaterialized += RegisterEagerLoadingStrategies;
处理程序方法如下所示:

private static void RegisterEagerLoadingStrategies(object sender, ObjectMaterializedEventArgs e)
{
  var context = (ObjectContext)sender;

  var cartItem = e.Entity as HotelCartItem;
  if (cartItem != null)
  {
    context.LoadProperty(cartItem, o => o.Hotel); 
  }
}
此解决方案存在N+1问题。N+1意味着,若主查询返回N个HotelCartItems,则将在数据库中执行N+1个查询(每个LoadProperty调用附加查询)。此外,每个加载的实体(不仅仅是HotelCartItem)都会调用此方法。所以这个解决方案对于加载大量的实体来说是非常糟糕的


从相关实体加载导航属性的另一种方法是将查询分为两个查询。第一个查询将加载CartItems,第二个查询将为第一个查询中加载的cart items加载Hotels(条件相同)。如果您的实体仍然连接到上下文,则应自动设置购物车项目中对酒店的引用。

我最后将查询分为几个部分:

  • 加载父项,即“购物车”
  • 对于我得到的每种不同类型(HotelCartItem和TransferCartItem),我都在db中查询了一组类型:
  • private IQueryable GetCartItemQuery(Guid CartID),其中T:CartItem
    {
    if(类型(T)=类型(酒店项目))
    {
    var q=来自db.cartimes.OfType()中的ci
    .包括(“酒店”)
    其中ci.CART_ID==CartID
    选择ci;
    返回q;
    }
    其他的
    {
    var q=来自db.cartimes.OfType()中的ci
    其中ci.CART_ID==CartID
    选择ci;
    返回q;
    }
    }
    
    称之为:

    var hotels = GetCartItemQuery<HotelCartItem>(CartID);
    var transfers = GetCartItemQuery<TransferCartItem>(CartID);
    
    var hotels=GetCartItemQuery(CartID);
    var transfers=GetCartItemQuery(CartID);
    
    三,。将CartItems添加到Cart对象的集合中

    context.ObjectMaterialized += RegisterEagerLoadingStrategies;
    
    private static void RegisterEagerLoadingStrategies(object sender, ObjectMaterializedEventArgs e)
    {
      var context = (ObjectContext)sender;
    
      var cartItem = e.Entity as HotelCartItem;
      if (cartItem != null)
      {
        context.LoadProperty(cartItem, o => o.Hotel); 
      }
    }
    
    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;
        }
    }
    
    var hotels = GetCartItemQuery<HotelCartItem>(CartID);
    var transfers = GetCartItemQuery<TransferCartItem>(CartID);