Warum fügt EF zuerst ein untergeordnetes Objekt (PersonalWorkRecord) mit einer Abhängigkeit vor dem Objekt ein, von dem es abhängig ist (TimesheetActivity)? Was sind meine Möglichkeiten, dies zu korrigieren?
Dies ist durch ein anderes System außerhalb meiner direkten Kontrolle vordefiniert.
Ich bin mir nicht sicher, warum ich / wie Entity Framework die Objekte, die ich habe, in der Reihenfolge einfüge, in der es ist, aber hier ist der Code, den ich verwende, um ein Elternteil und mehrere Kinder einzufügen.
%Vor%Wenn ich den Code ausführe, erhalte ich eine SQL-Fremdschlüsselverletzung im PersonalityWorkRecord (TimesheetActivityID), weil ich die Aktivität noch nicht hinzugefügt habe (siehe Trace).
%Vor%Hier ist der Code für die Kindobjektmethode. Ich habe diese Methode hinzugefügt, um die Objekte aus den Objekten der Zeiterfassungsobjekte zu entfernen, die keine Fremdschlüssel sind. Zum Beispiel habe ich ein Crew-Objekt, aber ich habe auch einen CrewID-Fremdschlüssel, also habe ich Crew = null gesetzt, damit EF nicht versucht, es einzufügen, da es bereits existiert.
%Vor%Nach meinem Verständnis wird ein dbContex.ObjectNameHere.Local hinzugefügt / geändert / gelöscht, wenn ein dbContext.Save () aufgerufen wird. (Abhängig davon, was der Entitätsstatus auch eingestellt ist.) Hier ist, was EF versucht, zu speichern, bevor ich die save () -Funktion aufruft und eine SQL-FK-Ausnahme erhalte. Dann bekomme ich die FK-Ausnahme.
Die INSERT-Anweisung steht im Konflikt mit der FOREIGN KEY-Einschränkung "FK_PersonnelWorkRecords_TimesheetActivities". Der Konflikt ist aufgetreten in der Datenbank "VPMTEST_GC", Tabelle "dbo.TimesheetActivities", Spalte 'ArbeitszeittabelleAktivitätID'. Die Anweisung wurde beendet.
Bitte lassen Sie es mich wissen, wenn ich etwas schreiben kann, um meine Frage zu beschreiben. Ich habe mich in google / SO nach Antworten umgesehen, aber bis jetzt keine solide Antworten, sieht es so aus, als ob EF die Reihenfolge des Einfügens von Objekten nicht bestimmen kann, wenn das Domänenmodell nicht anders eingerichtet ist? Ich bin nicht in der Lage, die Struktur der meisten Objekte zu ändern, wie sie von einem anderen System verwendet werden. Ich kann versuchen, meinen EF-Aufruf zu ändern, ich würde es vorziehen, Raw SQL nicht zu verwenden, da die Objekte ziemlich viel umfangreicher sind als die vereinfachten Versionen, die ich hier gepostet habe.
Ähnliche Fragen: Selbstreferenzierende Entität und Reihenfolge einfügen
In Ihrer RemoveChildObjects
Methode sehe ich die Zeile ...
Sie haben also offensichtlich die Eigenschaft der inversen Navigation von Timesheet.TimesheetActivities
auf null
gesetzt. Machst du dasselbe mit PersonnelWorkRecord.TimesheetActivity
und PersonnelWorkRecord.PersonnelWorkday
, d. H. Setzt du diese Eigenschaften auch in den geschachtelten null
Methoden auf RemoveChildObjects
?
Dies könnte ein Problem sein, weil Sie zwei verschiedene Pfade von Timesheet
bis PersonnelWorkRecord
haben, nämlich:
Beim Aufruf von db.Timesheets.Add(timesheet)
glaube ich, dass EF jede Verzweigung im Objektgraphen einzeln durchläuft und auf dem Pfad bestimmt, welche zusammenhängenden Objekte ("Knoten") abhängig sind und welche in einer Beziehung die Reihenfolge bestimmen Einfügen. timesheet
selbst ist Principal für alle seine Beziehungen, daher ist es klar, dass es zuerst eingefügt werden muss. Dann beginnt EF, durch eine der Sammlungen Timesheet.TimesheetActivities
oder Timesheet.PersonnelWorkdays
zu iterieren. Wer zuerst kommt, spielt keine Rolle. Scheinbar startet EF mit Timesheet.PersonnelWorkdays
. (Es würde das Problem nicht lösen, wenn es mit Timesheet.TimesheetActivities
beginnen würde, Sie würden die gleiche Ausnahme bekommen, aber mit PersonnelWorkRecord.PersonnelWorkday
anstelle von PersonnelWorkRecord.TimesheetActivity
.)% Co_de% hängt nur von PersonnelWorkday
ab, das bereits eingefügt wurde. Also, Timesheet
kann ebenfalls eingefügt werden.
Dann fährt EF mit PersonnelWorkday
weiter. In Bezug auf die PersonnelWorkday.PersonnelWorkRecords
Abhängigkeit von PersonnelWorkday
gibt es wieder kein Problem, da die PersonnelWorkRecord
bereits vorher eingefügt wurde. Aber wenn EF die PersonnelWorkday
Abhängigkeit von TimesheetActivity
entdeckt, wird es sehen, dass diese PersonnelWorkRecord
TimesheetActivity
ist (weil du sie auf null
gesetzt hast). Es wird nun vorausgesetzt, dass die Abhängigkeit durch die Fremdschlüsseleigenschaft null
alone beschrieben wird, die sich auf einen bestehenden Datensatz beziehen muss. Es fügt das TimesheetActivityID
ein und dies verletzt eine Fremdschlüsseleinschränkung.
Wenn PersonnelWorkRecord
nicht PersonnelWorkRecord.TimesheetActivity
ist, würde EF feststellen, dass dieses Objekt noch nicht eingefügt wurde, aber es ist das Prinzipal für null
. So kann es feststellen, dass diese PersonnelWorkRecord
eingefügt werden muss vor die TimesheetActivity
.
Ich würde hoffen, dass Ihr Code funktioniert, wenn Sie PersonnelWorkRecord
festlegen - oder zumindest nicht auf die beiden Navigationseigenschaften in null
. (Das Setzen der anderen Navigationseigenschaften wie PersonnelWorkRecord
, tsa.Creator
usw. auf tsa.Facility
sollte kein Problem darstellen, da diese verwandten Objekte tatsächlich bereits in der Datenbank vorhanden sind und Sie die korrekten FK-Eigenschaftswerte für diese Objekte festgelegt haben.)
Dies ist möglicherweise nicht mehr gültig, aber ist es eine Option, eine Transaktion zu verwenden und jedes untergeordnete Objekt einzeln hinzuzufügen?
Hinweis: Ich denke, dass die Lösung von Slauma vollständiger ist, ein Transaktionsanruf kann jedoch immer noch eine Option für andere sein, die ähnliche Probleme haben.
Tags und Links c# entity-framework tsql parent-child relational-database