1

Ich habe folgendes Modell (vereinfachte):Wie kann eine vererbte Eigenschaft in eine "ungleichmäßige" Vererbung mit Entity Framework integriert werden?

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

ausgedrückt "grafisch":

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

Jetzt möchte ich alle CartItems laden und beinhalten Daten aus der Hotelklassifizierung wenn Der Typ von CartItem ist ein HotelCartItem.

Dies ist, wie ich versuche, es zu tun, aber es schlägt mit einem "eine Navigationseigenschaft mit dem Namen 'Hotel' nicht deklarieren."

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

Wenn ich die .Include("Hotel") ist das Hotel Eigentum von CartItems von Typ Hotel auszulassen ist null.

Meine Frage:
Gibt es einen Weg, um dies zu umgehen?

Antwort

0

Ich beendete die Abfrage in mehrere Teile Aufspaltung:

  1. Legen Sie das übergeordnete Element, ein „Warenkorb“.
  2. Für jede der verschiedenen Arten Ich habe (HotelCartItem und TransferCartItem) abgefragt ich die db für einen Satz von nur dieser Art:
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; 
    } 
} 

es Anruf mit:

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

3. Fügen Sie die CartItems der Sammlung des Cart-Objekts hinzu.

0

Eager Laden von Navigationseigenschaften auf Unterklassen ist schwierig. Ich habe keinen anderen Weg gefunden, als sie separat zu laden. Der einfache Weg, das zu tun, ist das Registrieren benutzerdefinierten ObjectMaterialized Handler (nur in EF 4.0) auf Object:

context.ObjectMaterialized += RegisterEagerLoadingStrategies; 

Und die Handler-Methode wie folgt aussieht:

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); 
    } 
} 

Diese Lösung N + 1 Problem hat. N + 1 bedeutet, dass, wenn Ihre Hauptabfrage N HotelCartItems zurückgibt, N + 1 Abfragen in der Datenbank ausgeführt werden (jede LoadProperty ruft eine zusätzliche Abfrage auf). Auch diese Methode wird für jede geladene Entität aufgerufen (nicht nur für HotelCartItem). Diese Lösung ist wirklich schlecht für das Laden einer großen Anzahl von Entitäten.

Ein anderer Ansatz zum Laden von Navigationseigenschaften aus verwandten Entitäten besteht darin, Ihre Abfrage in zwei Abfragen aufzuteilen. Die erste Abfrage lädt CartItems und die zweite Abfrage lädt Hotels für die in der ersten Abfrage geladenen Artikel (gleiche Bedingungen). Verweise auf Hotels in Einkaufswagen-Artikeln sollten automatisch festgelegt werden, wenn Ihre Entitäten weiterhin mit dem Kontext verknüpft sind.

Verwandte Themen