2011-10-03 17 views
10

Zastanawiam się, czy istnieje możliwość, aby chętnych podmiotów związanych obciążenia do pewnej podklasy danej klasy.Entity Framework - Chętne ładowanie obiektów związanych z podklasą

struktury klasowej jest poniżej

Zamówienie ma związek z wielu klas bazowych podrząd (SuborderBase). Klasa MySubOrder dziedziczy z SuborderBase. Chcę podać ścieżkę do funkcji Include(), aby załadować elementy powiązane z MySubOrder (klientem) podczas ładowania zamówienia, ale dostałem błąd, twierdząc, że nie istnieje żadna zależność między SuborderBase a klientem. Ale istnieje powiązanie między MySubOrder a klientem.

Poniżej jest zapytanie, które nie

Context.Orders.Include("SubOrderBases").Include("SubOrderBases.Customers") 

Jak mogę określić, że jawnie?

Aktualizacja. Schemat podmiot jest poniżej enter image description here

+1

Prawdopodobnie brak rozwiązania z dużym obciążeniem. Oto obejście z projekcją (działa tylko trzeci fragment kodu w zaakceptowanej odpowiedzi, a nie drugi fragment, patrz komentarze do odpowiedzi): http://stackoverflow.com/questions/6586574/bottleneck-using-entity-framework- dziedzictwo. Tutaj (http://stackoverflow.com/questions/7203303/how-do-i-deeply-eager-load-an-entity-with-a-reference-to-an-instance-of-a-persist) było podobne pytanie bez żadnej odpowiedzi. – Slauma

+0

Czy możesz krótko szkicować klasy i relacje w kodzie ('Order',' SubOrderBase', 'MySubOrder',' Customer')? Patrząc na odpowiedzi wydaje się, że ludzie źle rozumieją twoje pytanie. Teraz też jestem niepewny po pierwszych odpowiedziach i komentarzach. – Slauma

+0

Dodano obrazek ze schematem klas – Gopher

Odpowiedz

13

Jest to rozwiązanie, które wymaga tylko jeden roundtrip:

var orders = Context.Orders 
    .Select(o => new 
    { 
     Order = o, 
     SubOrderBases = o.SubOrderBases.Where(s => !(s is MyOrder)), 
     MyOrdersWithCustomers = o.SubOrderBases.OfType<MyOrder>() 
      .Select(m => new 
      { 
       MyOrder = m, 
       Customers = m.Customers 
      }) 
    }) 
    .ToList() // <- query is executed here, the rest happens in memory 
    .Select(a => 
    { 
     a.Order.SubOrderBases = new List<SubOrderBase>(
      a.SubOrderBases.Concat(
      a.MyOrdersWithCustomers.Select(m => 
       { 
        m.MyOrder.Customers = m.Customers; 
        return m.MyOrder; 
       }))); 
     return a.Order; 
    }) 
    .ToList(); 

Jest to w zasadzie rzut do kolekcji anonimowych typów. Następnie wynik zapytania zostaje przekształcony w elementy i właściwości nawigacji w pamięci. (Działa również z wyłączonym śledzeniem).

Jeśli nie potrzebujesz jednostek, możesz pominąć całą część po pierwszym ToList() i pracować bezpośrednio z wynikiem w anonimowych obiektach.

Jeśli musisz zmodyfikować ten wykres obiektów i potrzebujesz śledzenia zmian, nie jestem pewien, czy to podejście jest bezpieczne, ponieważ właściwości nawigacji nie są ustawione w pełni podczas ładowania danych - na przykład MyOrder.Customers jest null po projekcji, a następnie ustawieniu Właściwości relacji w pamięci można wykryć jako modyfikację, która nie jest i powoduje problemy podczas wywoływania SaveChanges.

Prognozy są tworzone dla scenariuszy tylko do odczytu, a nie do modyfikacji. Jeśli potrzebujesz śledzenia zmian, prawdopodobnie bezpieczniejszym sposobem jest załadowanie pełnych elementów w wielu obiegach, ponieważ nie ma możliwości użycia Include w jednym obiegu, aby załadować cały wykres obiektów w twojej sytuacji.

+0

Dzięki! bardzo ciekawe rozwiązanie!Nie dokładnie to, co chciałem, ale myślę, że ten przykład będzie świetną inspiracją. – Gopher

+9

Świetna odpowiedź, ale jakże zadziwiająco głupio robić rzeczy. Każdy mógłby pomyśleć, że zespół EF przeoczył fakt, że relacyjne bazy danych mają relacje między tabelami. –

0

Załóżmy u załadowaniu listy zamówienia tak lstOrders, spróbuj tego:

foreach (Orders order in lstOrders) 
    order.SubOrderBases.Load(); 

i taka sama dla klientów ..

+2

tak, ale myślę jak to zrobić z zapytaniem 1 sql .. – Gopher

+2

spróbuj tego: Context.Orders.Include ("SubOrderBases"). Dołącz ("Klienci") – Boomer

Powiązane problemy