Ich habe kürzlich mit Entity Framework 4 gearbeitet und bin etwas verwirrt darüber, wann ObjectSet.Attach und ObjectSet.AddObject verwendet werden sollen .
Meinem Verständnis nach:
- Verwenden Sie "Anhängen", wenn bereits eine Entität im System vorhanden ist
- Verwenden Sie "AddObject", wenn Sie eine brandneue Entität erstellen
Wenn ich also eine neue Person erstelle , mache ich das.
var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();
Wenn ich eine vorhandene Person ändere , mache ich Folgendes :
var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();
Denken Sie daran, dies ist ein sehr einfaches Beispiel. In Wirklichkeit verwende ich Pure POCOs (keine Codegenerierung), Repository-Muster (nicht mit ctx.Persons) und Unit of Work (nicht mit ctx.SaveChanges). Aber "under the cover" ist das Obige, was in meiner Implementierung passiert.
Nun meine Frage - ich muss noch ein Szenario finden, in dem ich Attach verwenden musste .
Was fehlt mir hier? Wann müssen wir Attach verwenden?
BEARBEITEN
Zur Verdeutlichung suche ich nach Beispielen, wann Attach over AddObject verwendet werden soll (oder umgekehrt).
BEARBEITEN 2
Die folgende Antwort ist richtig (was ich akzeptiert habe), aber ich dachte, ich würde ein weiteres Beispiel hinzufügen, bei dem Anhängen nützlich wäre.
In meinem obigen Beispiel zum Ändern einer vorhandenen Person werden tatsächlich zwei Abfragen ausgeführt.
Eine zum Abrufen der Person (.SingleOrDefault) und eine zum Ausführen des UPDATE (.SaveChanges).
Wenn ich (aus irgendeinem Grund) bereits wusste, dass "Joe Bloggs" im System vorhanden ist, warum eine zusätzliche Abfrage durchführen, um ihn zuerst zu erhalten? Ich könnte das tun:
var ctx = new MyEntities();
var existingPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.Attach(existingPerson);
ctx.SaveChanges();
Dies führt dazu, dass nur eine UPDATE-Anweisung ausgeführt wird.
quelle
Antworten:
ObjectContext.AddObject und ObjectSet.AddObject :
Mit der AddObject- Methode können neu erstellte Objekte hinzugefügt werden, die nicht in der Datenbank vorhanden sind. Die Entität erhält einen automatisch generierten temporären EntityKey und ihr EntityState wird auf Added gesetzt . Wenn SaveChanges aufgerufen wird, wird dem EF klar, dass diese Entität in die Datenbank eingefügt werden muss.
ObjectContext.Attach und ObjectSet.Attach :
Auf der anderen Seite, Attach ist für Unternehmen verwendetdie bereits existieren in der Datenbank. Anstatt den EntityState auf "Hinzugefügt" zu setzen, führt "Anhängen" zu einem unveränderten EntityState. Dies bedeutet, dass er sich seit dem Anhängen an den Kontext nicht geändert hat. Es wird davon ausgegangen, dass Objekte, die Sie anhängen, in der Datenbank vorhanden sind. Wenn Sie die Objekte nach dem Anhängen ändern und SaveChanges aufrufen, wird der Wert des EntityKey verwendet, um die entsprechende Zeile zu aktualisieren (oder zu löschen), indem die entsprechende ID in der DB-Tabelle gefunden wird.
Darüber hinaus können Sie mit der Attach-Methode Beziehungen zwischen Entitäten definieren, die bereits im ObjectContext vorhanden sind, aber vorhanden sindwurde nicht automatisch verbunden. Grundsätzlich besteht der Hauptzweck von Anhängen darin, Entitäten zu verbinden, die bereits an den ObjectContext angehängt sind und nicht neu sind, sodass Sie Anhängen nicht zum Anhängen von Entitäten verwenden können, deren EntityState hinzugefügt wurde. In diesem Fallmüssen Sie Add () verwenden .
Angenommen, Ihre Personenentität verfügt über eine Navigationseigenschaft mit dem Namen Adressen, bei der es sich um eine Sammlung von Adressentitäten handelt . Angenommen, Sie haben beide Objekte aus dem Kontext gelesen, aber sie sind nicht miteinander verbunden, und Sie möchten es so machen:
quelle
Dies ist eine späte Antwort, kann aber anderen helfen, die dies finden.
Grundsätzlich kann eine "getrennte" Entität auftreten, wenn Sie eine Entität außerhalb des Bereichs "using" bearbeiten.
Wenn Sie einen anderen Bereich "using" eingeben, wird die Variable "e" getrennt, da sie zum vorherigen Bereich "using" gehört. Da der vorherige Bereich "using" zerstört wird, wird "e" getrennt.
So verstehe ich es.
quelle
Dies ist ein Zitat aus Programming Entity Framework: DbContext
quelle
Wie wäre es, wenn Sie sich nur auf den Primärschlüssel beziehen, anstatt ihn anzuhängen?
dh:
quelle