Hat jemand Vorschläge zur effizientesten Implementierung der Logik "Zeile aktualisieren, falls vorhanden, sonst einfügen" mithilfe von Entity Framework?
c#
entity-framework
Jonathan Wood
quelle
quelle
Antworten:
Wenn Sie mit angehängten Objekten arbeiten (Objekte, die aus derselben Instanz des Kontexts geladen wurden), können Sie einfach Folgendes verwenden:
Wenn Sie Kenntnisse über den Schlüssel des Objekts verwenden können, können Sie Folgendes verwenden:
Wenn Sie die Existenz des Objekts nicht anhand seiner ID bestimmen können, müssen Sie eine Suchabfrage ausführen:
quelle
using
Block. Ist es in Ordnung, den Kontext für eine Weile im Gedächtnis zu lassen? Zum Beispiel während der Lebensdauer eines Windows-Formulars? Normalerweise versuche ich, Datenbankobjekte zu bereinigen, um eine minimale Belastung der Datenbank sicherzustellen. Gibt es kein Problem damit, meinen EF-Kontext zu zerstören?Ab Entity Framework 4.3 gibt es
AddOrUpdate
im Namespace eine MethodeSystem.Data.Entity.Migrations
:welche von der doc :
Um den Kommentar von @ Smashing1978 zu beantworten , füge ich relevante Teile aus dem von @Colin bereitgestellten Link ein
Ich habe jedoch eine Situation, in der ich Daten von einem externen Dienst abrufe und vorhandene Werte per Primärschlüssel einfüge oder aktualisiere (und meine lokalen Daten für Verbraucher schreibgeschützt sind) - seit
AddOrUpdate
mehr als 6 Monaten in der Produktion bisher keine probleme.quelle
Die Magie passiert beim Anrufen
SaveChanges()
und hängt vom Strom abEntityState
. Wenn die Entität eine hatEntityState.Added
, wird sie der Datenbank hinzugefügt. Wenn sie eine hatEntityState.Modified
, wird sie in der Datenbank aktualisiert. Sie können also eineInsertOrUpdate()
Methode wie folgt implementieren :Mehr über EntityState
Wenn Sie nicht überprüfen können
Id = 0
, ob es sich um eine neue Einheit handelt oder nicht, überprüfen Sie die Antwort von Ladislav Mrnka .quelle
Wenn Sie wissen, dass Sie denselben Kontext verwenden und keine Entitäten trennen, können Sie eine generische Version wie die folgende erstellen:
db
kann natürlich ein Klassenfeld sein, oder die Methode kann statisch und eine Erweiterung gemacht werden, aber das sind die Grundlagen.quelle
Ladislavs Antwort war knapp, aber ich musste einige Änderungen vornehmen, damit dies in EF6 (Datenbank zuerst) funktioniert. Ich habe meinen Datenkontext mit meiner Methode on AddOrUpdate erweitert, und bisher scheint dies mit getrennten Objekten gut zu funktionieren:
quelle
Meiner Meinung nach ist es erwähnenswert, dass Sie sich mit dem neu veröffentlichten EntityGraphOperations for Entity Framework-Code zunächst das Schreiben einiger sich wiederholender Codes zum Definieren der Zustände aller Entitäten im Diagramm ersparen können. Ich bin der Autor dieses Produkts. Und ich habe es im Github , im Code-Projekt ( einschließlich einer schrittweisen Demonstration und zum Herunterladen eines Beispielprojekts) und im Nuget veröffentlicht .
Der Status der Entitäten wird automatisch auf
Added
oder gesetztModified
. Und Sie werden manuell auswählen, welche Entitäten gelöscht werden müssen, wenn sie nicht mehr vorhanden sind.Das Beispiel:
Nehmen wir an, ich habe ein
Person
Objekt.Person
könnte viele Telefone haben, ein Dokument und könnte einen Ehepartner haben.Ich möchte den Status aller Entitäten bestimmen, die in der Grafik enthalten sind.
Wie Sie wissen, können beim Definieren des Status der Telefonentität eindeutige Schlüsseleigenschaften eine Rolle spielen. Für solche speziellen Zwecke haben wir eine
ExtendedEntityTypeConfiguration<>
Klasse, die von erbtEntityTypeConfiguration<>
. Wenn wir solche speziellen Konfigurationen verwenden möchten, müssen wir unsere Zuordnungsklassen von erbenExtendedEntityTypeConfiguration<>
und nicht vonEntityTypeConfiguration<>
. Beispielsweise:Das ist alles.
quelle
Fügen Sie else ein, aktualisieren Sie beide
quelle
Überprüfen Sie die vorhandene Zeile mit Beliebig.
quelle
Alternative für @LadislavMrnka Antwort. Dies gilt für Entity Framework 6.2.0.
Wenn Sie ein bestimmtes
DbSet
Element haben, das entweder aktualisiert oder erstellt werden muss:Dies kann jedoch auch für ein Generikum
DbSet
mit einem einzelnen Primärschlüssel oder einem zusammengesetzten Primärschlüssel verwendet werden.quelle
Korrigiert
quelle