Entity Framework Viele-zu-viele Fragen

8

Bitte helfen Sie einem EF n00b beim Entwurf seiner Datenbank. Ich habe mehrere Unternehmen, die mehrere Produkte herstellen, daher gibt es eine Viele-zu-Viele-Beziehung zwischen Unternehmen und Produkten. Ich habe eine Zwischentabelle, Company_Product, die sie in Beziehung setzt.

Jede Firma / Produktkombination hat eine eindeutige Artikelnummer. Zum Beispiel haben Acme-Widgets die SKU 123, aber Omega-Widgets haben die SKU 456. Ich habe die SKU als Feld in die Company_Product-Zwischentabelle aufgenommen.

EF hat ein Modell mit einer 1: * - Beziehung zwischen den Tabellen Company und Company_Product und einer 1: * - Beziehung zwischen den Tabellen Product und Company_Product generiert. Ich möchte wirklich eine : Beziehung zwischen Unternehmen und Produkt. Vor allem aber gibt es keine Möglichkeit, direkt vom Modell auf die SKU zuzugreifen.

Muss ich die SKU in eine eigene Tabelle schreiben und einen Join schreiben, oder gibt es einen besseren Weg?

    
Sisiutl 02.07.2010, 17:55
quelle

2 Antworten

33

Ich habe das gerade in einem neuen VS2010-Projekt (EFv4) getestet, und hier ist, was ich gefunden habe:

Wenn Ihre assoziative Tabelle in der Mitte (Company_Product) NUR die 2 Fremdschlüssel zu den anderen Tabellen (CompanyID und ProductID) enthält, endet die Modellierung der Viele-zu-viele-Beziehung dann, wenn Sie dem Designer alle 3 Tabellen hinzufügen. Es generiert nicht einmal eine Klasse für die Company_Product-Tabelle. Jedes Unternehmen hat eine Produktsammlung und jedes Produkt hat eine Firmensammlung.

Wenn Ihre assoziative Tabelle (Company_Product) jedoch andere Felder hat (z. B. SKU, ihren eigenen Primärschlüssel oder andere beschreibende Felder wie Daten, Beschreibungen usw.), erstellt der EF-Modellierer eine separate Klasse was du schon gesehen hast.

Die Klasse in der Mitte mit 1: * Beziehungen zu Unternehmen und Produkt zu haben, ist keine schlechte Sache, und Sie können immer noch die gewünschten Daten mit einigen einfachen Abfragen erhalten.

%Vor%

Es ist zwar nicht so einfach, die Beziehungen des Modells zu steuern, wenn Sie beispielsweise bereits Entitätsobjekte geladen haben, aber dafür ist eine Datenschicht zuständig. Verkapseln Sie die Abfragen, die die gewünschten Daten erhalten. Wenn Sie diese mittlere Company_Product-Klasse wirklich loswerden möchten und die Viele-zu-Viele direkt im Klassenmodell darstellen möchten, müssen Sie die Company_Product-Tabelle entfernen, um nur die 2 Fremdschlüssel zu enthalten, und loswerden der SKU.

Eigentlich sollte ich nicht sagen, dass du das tun musst ... du könntest vielleicht einige Änderungen am Designer vornehmen und es auf diese Weise einrichten. Ich werde es versuchen und berichten.

AKTUALISIEREN

Wenn ich die SKU in der Company_Product-Tabelle behalte (dh mein EF-Modell hatte 3 Klassen, nicht 2; es hat die Klasse Company_Payload mit einem 1: * zu den anderen 2 Tabellen erstellt), habe ich versucht, eine Verknüpfung direkt zwischen Firma und Produkt. Die Schritte, denen ich folgte, waren:

  • Klicken Sie mit der rechten Maustaste auf die Klasse Company im Designer
  • Hinzufügen & gt; Verein
  • Setze "Ende" auf der linken Seite, um Firma zu sein (sollte es schon sein)
  • Setzen Sie "Ende" auf der rechten Seite auf Produkt
  • Ändere beide Multiplizitäten zu "* (Many)"
  • Die Navigationseigenschaften sollten "Produkte" und "Firmen"
  • heißen
  • Drücken Sie OK.
  • Rechtsklick auf die Assoziation im Modell & gt; Klicken Sie auf "Tabellenzuordnung"
  • Unter "Hinzufügen einer Tabelle oder Ansicht" wählen Sie "Company_Product"
  • Karte Firma - & gt; ID (links) bis CompanyID (rechts)
  • Kartenprodukt - & gt; ID (links) bis ProductID (rechts)

Aber es funktioniert nicht. Es gibt diesen Fehler: Fehler 3025: Problem beim Zuordnen von Fragmenten ab Zeile 175: Muss die Zuordnung für alle Schlüsseleigenschaften (Company_Product.SKU) der Tabelle Company_Product angeben.

Diese bestimmte Verknüpfung ist daher ungültig, weil sie Company_Product als Tabelle verwendet, aber das SKU-Feld keinem Objekt zuordnet.

Auch während ich das recherchierte, stieß ich auf diesen "Best Practice" Leckerbissen aus dem Buch Entity Framework 4.0 Recipes (beachten Sie, dass sie für eine Assoziationstabelle mit zusätzlichen Feldern neben zwei FKs die zusätzlichen Felder als bezeichnen die "Nutzlast". In Ihrem Fall ist SKU die Nutzlast in Company_Product.

  

Best Practice

     

Leider ein Projekt   das beginnt mit mehreren,   Nutzlast-frei, viele-zu-viele   Beziehungen enden oft mit   mehrere, Nutzlast-reiche, viele-zu-viele   Beziehungen. Refactoring eines Modells,   besonders spät in der Entwicklung   Zyklus, um Nutzlasten in der   Viele-zu-viele-Beziehungen können sein   langweilig. Nicht nur sind zusätzliche   Entitäten eingeführt, aber die Abfragen   und Navigationsmuster durch die   Beziehungen ändern sich auch. Etwas   Entwickler argumentieren, dass jeder   Viele-zu-viele-Beziehung sollte beginnen   mit etwas Payload, typischerweise a   synthetischer Schlüssel, also das Unvermeidliche   Hinzufügung von mehr Nutzlast hat   deutlich weniger Auswirkungen auf die   Projekt.

     

Hier ist also die beste Vorgehensweise.   Wenn Sie eine Nutzlast haben,   Viele-zu-viele-Beziehung und du   denke, dass es eine Chance gibt, dass es könnte   im Laufe der Zeit ändern, um eine Nutzlast aufzunehmen,   Beginnen Sie mit einer zusätzlichen Identitätsspalte in   die Verbindungstabelle. Beim Importieren der   Tabellen in Ihr Modell, werden Sie bekommen   zwei Eins-zu-viele-Beziehungen, die   bedeutet der Code, den Sie schreiben und das Modell   Sie werden für jede Nummer bereit sein   von zusätzlichen Nutzlastspalten, die   Kommen Sie mit, wenn das Projekt reift. Das   Kosten einer zusätzlichen Ganzzahlidentität   Spalte ist normalerweise ein ziemlich kleiner Preis   zu zahlen, um das Modell mehr zu halten   flexibel.

(Aus Kapitel 2. Grundlagen der Modellierung von Entitätsdaten, 2.4. Modellierung einer Viele-zu-Viele-Beziehung mit einer Payload)

Klingt wie ein guter Rat. Zumal Sie bereits eine Payload (SKU) haben.

    
Samuel Meacham 02.07.2010, 18:13
quelle
2

Ich möchte nur das Folgende zu Samuels Antwort hinzufügen:

Wenn Sie direkt von einer Seite einer Viele-zu-Viele-Beziehung (mit Payload) zu der anderen abfragen möchten, können Sie den folgenden Code verwenden (unter Verwendung des gleichen Beispiels):

%Vor%

Die Variable products würde dann alle Product Datensätze sein, die dem Company c Datensatz zugeordnet sind. Wenn Sie die Artikelnummer für jedes Produkt hinzufügen möchten, können Sie eine anonyme Klasse wie folgt verwenden:

%Vor%

Sie können die erste Abfrage in einer schreibgeschützten Eigenschaft der Einfachheit halber wie folgt kapseln:

%Vor%

Sie können das nicht mit der Abfrage ausführen, die die SKU enthält, da Sie keine anonymen Typen zurückgeben können. Sie müssten eine bestimmte Klasse haben, die in der Regel entweder durch Hinzufügen einer nicht zugeordneten Eigenschaft zur Klasse Product oder durch Erstellen einer anderen Klasse, die von Product erbt, die eine SKU-Eigenschaft hinzufügen würde. Wenn Sie jedoch eine geerbte Klasse verwenden, können Sie keine Änderungen daran vornehmen und lassen Sie sie von EF verwalten - das wäre nur für die Anzeige nützlich.

Prost. :)

    
CptRobby 03.07.2013 18:05
quelle