Entity Framework 3.5 schaffen Entities on the fly

Nehmen wir ein vereinfachtes datamodell an, das aus zwei Tabellen, Buch und Autor besteht, die durch eine Fremdschlüsselbeschränkung "Book.AuthorId = Author.Id" verknüpft sind.

Jetzt sagst du, du hast eine kleine list von Büchern:

Title Author --------------------------------------------------------- The Selfish Gene Richard Dawkins Why Is Sex Fun Jared Diamond The Ancestors Tale Richard Dawkins 

Wie importierst du diese, ohne eine Gazillion-Rundreise in die DB zu machen?

Ich bin neu bei EF aber dachte, es würde mir erlauben, Entitäten dem objectkontext hinzuzufügen, und dann würden sie in diesem Zusammenhang verfügbar sein, auch wenn sie noch nicht gespeichert sind. Das scheint nicht der Fall zu sein. Grundsätzlich mache ich das:

 void Import() { ctx = new Database(); foreach (...) { Import(bookTitle, authorName); } ctx.SaveChanges(); } void Import(string bookTitle, string authorName) { var author = ctx.Authors.Single(a => a.Name == authorName); if (author == null) { author = new Author(); author.Name = authorName; ctx.AddToAuthors(author); } var book = new Book(); book.Author = author; ctx.AddToBooks(book); } 

Aber EF findet nie einen Autor, den ich schon hinzugefügt habe, also macht es jedes Mal ein neues. Daher sind die beiden Bücher von Dawkins mit zwei verschiedenen Autorenobjekten in der Grafik verwandt, was natürlich falsch ist.

Als nächstes schafft es bei SaveChanges EF, den ersten Buch- und Autor-datasatz einzufügen, aber dann stürzt er auf Nummer zwei mit einer PRIMARY-KEY-VERLETZUNG, weil er versucht, Id = 0 für jedes object zu verwenden.

 System.Data.UpdateException: An error occurred while updating the entries. See the InnerException for details. ---> System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK_Book'. Cannot insert duplicate key in object 'dbo.Book'. 

Ich habe versucht, die Definition für die ID-Felder in INT IDENTITY (1,1) in MSSQL zu ändern und dann das model zu aktualisieren. Die Festlegung der DB definieren die Schlüsselwerte ist sowieso besser als mit Entity Framework (oder jedem Client) tun es. Aber das scheint überhaupt nicht zu unterstützen. EF scheint nicht bemerkt zu haben, dass meine Schlüssel IDENTITY Spalten sind, als ich das model aktualisiert habe. Es führt nur zu

 System.Data.UpdateException: An error occurred while updating the entries. See the InnerException for details. ---> System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'Book' when IDENTITY_INSERT is set to OFF. 

Das genaue Symptom ist vorhanden, ob ich das model aktualisiere oder nicht nach dem Umstieg von "Id INT PRIMARY KEY" auf "Id INT IDENTITY (1,1) PRIMARY KEY" für die Spaltendefinition, was ist, was führt mich zu vermuten, dass Microsoft didn Denken Sie daran, DENKEN SIE ÜBER Identitätsspalten, obwohl ich hoffe, dass ich das falsch bin!

Ich weiß, es gibt wirklich viele Fragen, die hier lauern, aber da nichts in Entity Framework wie erwartet funktioniert, wähle ich die übergeordnete Frage als "gegeben dieses datamodell und diese data zu importieren, was ist ein guter path, um es mit Entity Framework 3.5 zu tun ? "

Bitte vergewissere mich, dass ich EF 4.0 stattdessen benutze, da das außerhalb meiner Kontrolle liegt. 🙂

Meine Frage basiert auf einem Missverständnis – in der Tat das Hinzufügen der objecte zum objectkontext ohne memoryn macht sie im objectkontext verfügbar.

Was war wirklich los ist: Ich bin Triggern Logik in einer .net Versammlung aus powershell Skript mit Reflection.Load. Als ich Änderungen im .net-Projekt vorgenommen habe, habe ich es wieder aufgebaut und GAC-ed es, dann lerne mein PowerShell-Skript, ich habe immer noch den alten Code ausgeführt. Grundsätzlich ist der Code von MyAssembly.dll in die powershell-session verknüpft, also wenn ich das Skript erneut ausführt, spielt es keine Rolle, dass eine neue Version des Codes zum GAC implementiert wurde …

Die PK-Verletzung macht dann Sinn, da mein Code der Entität keine ID zuweist und es mehr als einen Autor gibt – ich habe versucht, beide mit ID = 0 zu speichern.

Die "kann keinen expliziten Wert insert, wenn IDENTITY INSERT ausgeschaltet ist" jetzt auch sinnvoll, weil ich meine database geändert hatte, aber immer noch den Code ausführte, der davon ausgegangen wurde, dass die ID von eingefügt werden soll.

Kurzum, was das Problem beharrte, war, meine PowerShell-session zu schließen und eine neue zu starten.