2009-09-22 22 views
8

Ich denke, es gibt einen ähnlichen Beitrag hier darüber, aber nicht genau das gleiche ...Entity Framework - Vererbung mit .Include?

Ich habe zwei Einheiten in meinem EF-Modell - nennen wir sie Person und Entwickler, wobei letzterer von ersteren erbt.

Ich habe auch eine Assoziation auf Entwickler namens Qualifikationen. Dies ist in der Entität Person nicht sichtbar.

Wenn ich eine Abfrage gegen den Kontext schreibe, wie ich automatisch.() Die Qualifikationen des Entwicklers z.

von Mitarbeitern in context.Employee .INCLUDE („Qualifikationen“) wählen Mitarbeiter

funktioniert nicht ... EF beklagt, dass die Beziehung existiert nicht (ich nehme an, weil es nicht existiert auf Employee - aber es gibt keine Developer-Entität im Kontext, nur Employee).

Antwort

0

Ich bin nicht vertraut mit EF, aber das sieht für mich wie ein Standard-Vererbungsproblem aus. Wenn Sie auf die eindeutigen Eigenschaften einer untergeordneten Klasse aus einer Sammlung von übergeordneten Objekten zugreifen möchten (wobei die tatsächlichen Objekte Instanzen der untergeordneten Klasse sein können oder nicht), müssen Sie den Objekttyp überprüfen und an das untergeordnete Objekt übergeben Gegebenenfalls können Sie dann auf die einzigartigen Eigenschaften zugreifen.

Was würden Sie erwarten, dass die angegebene Anweisung zurückkommt, wenn einige oder alle Objekte nicht Entwickler waren?

+0

Hi ... Es sollte nicht versuchen, in den untergeordneten Entitäten für die Basisklasse zu laden, da sie nicht vorhanden sind. Ich mache das Casting, um die Kindeigenschaften usw. zu überprüfen - aber der Hauptpunkt des Includes ist es, alles auf einmal zu lesen (bedenken Sie, dass EF kein Lazy Loading unterstützt). –

+0

Ich denke, ich würde geneigt sein, Person nicht unterzuordnen, sondern eine andere Klasse namens Developer, die eine Person hat, auf diese Weise können Sie wahrscheinlich eine Sammlung von Person abrufen und durch Zuordnung in der Lage sein, diejenigen abrufen, die von einem Entwickler referenziert werden Von diesem Developer-Objekt können diejenigen mit Qualifikationen gefunden werden. Ich bin mir wirklich nicht sicher, ob es möglich ist, das zu tun, was Sie mit der von Ihnen angegebenen Klassenhierarchie tun wollen. – Lazarus

2

Wie dies etwa:

var results = from developer in ctx.Employee.OfType<Developer>() 
       select new {developer, Qualifications = developer.Qualifications}; 

Um die Dinge interessant sind hier:

  1. wir Mitarbeiter ohne dass nicht Entwickler
  2. wir ihre Qualifikationen dann Projizieren sind und als ein Nebeneffekt dieser Projektion, etwas namens fixup mit füllen jede Entwickler.Qualifikationen auch. I.e. Dies ist eine andere Möglichkeit, die gleichen Effekt wie Include() zu erreichen.

, wenn Sie anschließend dies tun:

var developers = from anon in developers.AsEnumerable() 
       select anon.Developer; 

Sie werden nur Entwickler bekommen, und sie werden auch ihre Qualifikationen geladen haben.

Siehe Tip 1 für weitere Informationen darüber, warum diese

Hoffnung funktioniert diese

über dieses Problem

Alex

+0

Hallo - danke für den Vorschlag. Ich werde es ausprobieren! Es hört sich ein bisschen so an, als wäre es keine "offiziell unterstützte" Lösung, obwohl es von diesem Link stammt. Ich habe es vorübergehend durch den Aufruf von Load auf die Child-Sammlung bekommen, aber dies führt zu einem separaten SQL-Aufruf, so dass ich es gerne vermeiden möchte. Danke nochmal. –

+1

Obwohl eine Sache, die ich gerade realisiert habe - die Methode, in der dieser Code lebt, sollte in der Lage sein, mit abgeleiteten und nicht abgeleiteten Klassen zu arbeiten, dh ich sollte eine Sammlung von Mitarbeitern erhalten, von denen einige Entwickler sein können (wer sollte dann? haben ihre Qualifikationen ausgefüllt). –

+1

Das Bit, das nicht offiziell auf dem Link unterstützt wird, war das Sortieren der Sammlung. Das tatsächliche Laden der Sammlung (alles, was oben verwendet wird) wird vollständig unterstützt. –

10

Ich bin gekommen, hilft und experimentierte ein wenig. Hier ist, was ich gefunden habe mit LINQ 2 Entity gearbeitet.

Angenommen, wir haben in Ihrem Beispiel Person < - Entwickler ---- Qualifikationen.

Wenn Sie einen Entwickler mit Qualifikationen auswählen möchten, würden Sie dies tun.

var dev = (from d in context.Persons.OfType<Developer> 
          .Include("Qualifications") 
      where d.ID == id 
      select d).FirstOfDefault(); 

Jetzt können sagen, dass wir eine weitere Verbindung zwischen Person und Adresse haben, können wir auch Adresse in die Auswahl auch mit LINQ 2 Entity umfassen.

Beachten Sie, wie ich die Dinge, die ich brauchte, bevor ich den Typ konvertiert und auch nach der Konvertierung wieder aufgenommen habe. Beide Includes sollten jetzt problemlos zusammenarbeiten. Ich habe diese Methoden getestet und beide funktionieren. Ich hoffe, sie arbeiten für Sie, vorausgesetzt, Sie haben Ihre Vererbung korrekt eingerichtet.

GL.

2

Basierend auf Tri Q Antwort, aber für diejenigen, die den '.load()' Ansatz bevorzugen, können Sie verwenden:

context.Persons.OfType<Developer>().Include(t => t.Qualifications).Load(); 

Ich benutze es in meinem DbContext. Ich habe die LoadDb() -Methode erstellt, die alle benötigten Daten lädt. So kann ich es aus vielen Projekten verwenden.

Verwandte Themen