1

私は次のモデル(単純化)を持っている:Entity Frameworkで "不均一"継承に継承プロパティを含めるにはどうすればよいですか?

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

としては、 "グラフィック" 表現:

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

を今、私はすべてのCartItemsをロードすると、もしホテルクラスからのデータを含めますCartItemのタイプはHotelCartItemです。

これはこれを行う方法ですが、「 'Hotel'という名前のナビゲーションプロパティを宣言しません」というエラーが表示されます。

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

私は.Include("Hotel")を除外した場合型ホテルのCartItemsのホテルプロパティはnullです。

私の質問:
これを回避する方法はありますか?

答えて

0

私はいくつかの部分にクエリを分割することになった:

  1. 親項目、「カート」をロードします。私が得たさまざまなタイプ(HotelCartItemとTransferCartItem)のそれぞれについて
  2. 私はそのタイプのセットのためのDBを照会:

    var hotels = GetCartItemQuery<HotelCartItem>(CartID); 
    var transfers = GetCartItemQuery<TransferCartItem>(CartID); 
    
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; 
    } 
} 

はでそれを呼び出します

3。 CartItemsをCartオブジェクトのコレクションに追加します。

0

サブクラスでナビゲーションプロパティを読み込むのは難しいです。私はそれらを別々にロードする以外の方法はありませんでした。それを行うための簡単な方法は、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個のCheapartItemを返す場合、データベース内でN + 1個のクエリを実行することを意味します(各LoadPropertyは追加クエリを呼び出します)。また、このメソッドは、ロードされたすべてのエンティティ(HotelCartItemだけでなく)に対して呼び出されます。このため、このソリューションは、多数のエンティティをロードする場合には本当に悪いことです。

関連するエンティティからナビゲーションプロパティをロードするもう1つのアプローチは、クエリを2つのクエリに分割することです。最初のクエリはCartItemsを読み込み、2番目のクエリは最初のクエリ(同じ条件)に読み込まれたカート項目のホテルを読み込みます。エンティティがまだコンテキストに関連付けられている場合は、カートアイテム内のホテルへの参照は自動的に設定されます。

関連する問題