Ich habe jetzt mehrere Tage damit verbracht, dieses Problem zu lösen. Während ich ein einfaches Projekt machte, um mein Problem zu veranschaulichen, stolperte ich über eine mögliche Lösung. Das ist also eine doppelte Frage.
Aber zuerst, ein wenig Hintergrundinfo:
Ich habe gerade mit Entity Framework 4.1 (EF) und Code First begonnen, um die Modelle für mein ASP.NET MVC-Projekt zu erstellen. Ich brauche ein paar ähnliche Modelle:
%Vor%Und der DbContext:
%Vor%(Bitte entschuldigen Sie das lahme Beispiel, das ist es, was mein Freitag-frittiertes Gehirn mir einfallen lassen konnte.)
Eine Familie kann mehrere Mütter und mehrere Väter haben. Und ein Kind hat eine Mutter und einen Vater. Ich habe bei meiner Arbeit mit einem der .NET-Gurus nachgesehen, der zustimmte, dass es nichts Außergewöhnliches daran gibt. Zumindest soweit wir sehen können.
Aber wenn ich den Code ausführe, bekomme ich diese Ausnahme:
System.Data.SqlServerCe.SqlCeException: Die referenzielle Beziehung führt zu einer zyklischen Referenz, die nicht erlaubt ist. [Einschränkungsname = Mother_Family]
Ich sehe den Zyklus: Family - Mother - Child - Father - Family
. Aber wenn ich die Datenbanktabellen selbst erstellt habe (was ich nicht vorziehe, das mag ich an Code First), wäre das eine absolut gültige Datenstruktur, soweit ich das beurteilen kann.
Meine erste Frage lautet also: Warum ist das ein Problem, wenn Sie zuerst Code verwenden? Gibt es eine Möglichkeit, EF mitzuteilen, wie der Zyklus richtig gehandhabt wird?
Als ich dann anfänglich schrieb, während ich ein einfaches Projekt zur Veranschaulichung meines Problems erstellte, stolperte ich zufällig über eine mögliche Lösung. Bei der Definition meiner Modelle habe ich einfach einige Eigenschaften vergessen. Im folgenden Beispiel habe ich die Teile der Modelle, die ich vergessen habe, auskommentiert, anstatt sie zu entfernen:
%Vor% Das Entfernen dieser SomethingID
-Referenzeigenschaften scheint mein Problem zu lösen. Wie Sie im Controller des Beispielprojekts sehen können, mit dem ich am Ende dieses Posts verlinke, kann ich immer noch den ganzen Zyklus herumfahren und Sachen wie mothers.First().Family.Fathers.First().Children.First().Mother.Family.Name
ohne Probleme machen. Aber alle Tutorials und Beispiele über EF und Code First Modellierung, die ich mir angesehen habe (zB dieses von Scott Guthrie ) enthält diese Eigenschaften, so dass es sich falsch anfühlt, sie nicht zu verwenden.
Und so ist meine zweite Frage: Wird es irgendwelche Nachteile und Probleme geben, die ich noch nicht entdeckt habe?
Laden Sie hier ein Beispielprojekt herunter: Ссылка und öffnen Sie TestSolution.sln. Die Eigenschaften sind im Beispielprojekt auskommentiert. Entfernen Sie die Kommentarzeichen für die Zeilen in TestModels.cs, um die Eigenschaften hinzuzufügen, die zu der zyklischen Referenzausnahme führen.
Anmerkung: Die Lösung erstellt und seduliert eine SQL CE-Datenbank unter c: \ TestApp.sdf
Update, Dezember 2011: Ich habe dieses Problem nie technisch gelöst, aber ich habe meinen Job gekündigt und einen anderen Job gefunden, bei dem ich keine Microsoft-Technologien verwenden muss. Diese Art von gelöstem mein Problem:)
Wie der technische Support an der alten Stelle beim Beheben von Problemen geschrieben hat: "Eine Problemumgehung oder Lösung wurde bereitgestellt".
Aber wenn ich die Datenbanktabellen selbst erstellt habe (was ich nicht vorziehe, das ist, was ich an Code First mag) es wäre eine vollkommen gültige Datenstruktur, soweit ich das beurteilen kann.
Das sollten Sie überprüfen. Die Ausnahme kommt direkt von der Datenbank und nicht von Entity Framework. Es ist wahrscheinlich, dass auch eine Tabellenstruktur mit denselben Einschränkungen, die von Hand erstellt wurden, ungültig ist. Beachten Sie, dass Ihre Fremdschlüsseleigenschaften Mother.FamilyID
, Father.FamilyID
, Child.MotherID
und Child.FatherID
nicht nullable sind, sodass sie erforderliche Beziehungen darstellen und die entsprechenden Spalten in der Datenbank ebenfalls nicht nullfähig sind .
Wenn Sie all diese Eigenschaften aus Ihren Modellklassen entfernen, werden Ihre Beziehungen plötzlich optional , weil die Navigationseigenschaften null
sein können. Dies ist jetzt ein anderes Modell, da die FK-Spalten in der DB Nullable sein können! Anscheinend ist dies ein erlaubtes Modell.
Wenn Sie in Ihrem Modell noch Fremdschlüsseleigenschaften haben möchten, die eine optionale anstelle einer erforderlichen Beziehung darstellen, können Sie Typen verwenden, die nicht vermerkt sind: public int? FamilyID { get; set; }
, public int? MotherID { get; set; }
, etc.
Dies ist ein bekanntes Problem und Sie sind nicht der erste, der darauf stößt. Aus dem, was ich gehört habe, arbeiten sie an einer besseren Lösung in der kommenden Version von WCF, aber vorläufig aus meiner Erfahrung sind Sie besser dran, DataContracts zu erstellen, die die Daten darstellen, die über den Draht gesendet werden, wodurch die Datenstruktur verändert wird um die zyklische Referenz zu entfernen.
Ich weiß, dass es ein Schmerz ist, aber es gibt andere Vorteile, die Sie wahrscheinlich noch andere Änderungen an Strukturen vornehmen werden, die Ihre Kunden sowieso verbrauchen, anstatt sie mit den Objekten zu spielen, wie sie in Ihrer db
Ich hatte das gleiche Problem, aber ich löste es mit dem Rat in dieser Antwort Zuerst Entity Framework Code - zwei Fremdschlüssel aus derselben Tabelle , der besser funktioniert als den Typ der Schlüsselspalten als optional zu ändern.
Tags und Links c# entity-framework-4.1 code-first modeling