Frage

Ich habe eine übergeordnete Entität

foo was in der Datenbank vorhanden ist, ich habe eine Eigenschaft bar auf dieser Entität (Eins-zu-viele-Beziehung).

Foo ist getrennt, weil es mit WebApi deserialisiert wurde, also mache ich das foo

context.Foos.AddOrUpdate(foo);

Auch wenn es ein neues gibt bar Wenn Sie einen daran angehängten Verweis hinzufügen, wird er nicht gespeichert, aber für eine andere Beziehung, die wir haben, funktioniert es auf diese Weise, nämlich eine Viele-zu-Viele-Beziehung.Wenn ich dieser Sammlung eine neue Entität hinzufüge, wird sie in ihrer Tabelle gespeichert und außerdem wird eine Zeile zur Beziehungstabelle hinzugefügt.

Wenn ich mache context.Bars.AddOrUpdate(foo.Bar); bevor Sie anrufen context.Foos.AddOrUpdate(foo); Der neue Balken wird korrekt in der Bar-Tabelle gespeichert, der Foo-Tabelle wird jedoch nicht die richtige Bar-ID hinzugefügt

@Yuliam Chandra

Wenn ich Ihre Antwort richtig verstehe (ich glaube, Sie verwechseln in Ihrer Antwort Bars und Foos), sollte das funktionieren?

var foo = new Foo();
foo.FooId = 524 //Existing foo;

foo.Bar = new Bar(); //Completely new bar    
db.Foos.AddOrUpdate(foo);
db.SaveChanges();

Aber das ist nicht der Fall

War es hilfreich?

Lösung

Für die Arbeit mit nicht verbundenen Objekten ist zusätzlicher Code erforderlich.

Wenn Sie mit nicht verbundenen Objekten arbeiten, müssen Sie die Synchronisation manuell verwalten.

Quelle

Wenn Bar Ist eine vorhandene Entität, müssen Sie sie zuerst anhängen Foo wird hinzugefügt als Bar's Kinder.

if (foo.Bar.Id != 0)
{
    context.Bars.Attach(foo.Bar);
    context.Foos.AddOrUpdate(foo);
}

Das Beispiel des obigen Codes ist ähnlich mit Course (Foo) Und Department (Bar) Beispiel in Dieser Artikel.

Aber falls Bar ist eine neue Entität, die Sie nur hinzufügen müssen Foo, Dann Bar wird auch hinzugefügt.

else
{
    context.Foos.Add(foo);
}

Eine andere Sorte kann überprüft werden meine Antwort.

aktualisieren

Bevor ich es weiter erkläre, möchte ich identischen Code zeigen.

  • db.Set<T>().Add(instance) ist gleich db.Entry(instance).State = EntityState.Added;
  • db.Set<T>().Attach(instance) ist gleich db.Entry(instance).State = EntityState.Unchanged;

In der vorherigen Antwort wurden zwei Bedingungen erläutert.

  • Neues Foo und bestehende Bar

    context.Bars.Attach(foo.Bar);

    context.Foos.AddOrUpdate(foo);

  • Neues Foo und neue Bar

    context.Foos.Add(foo);

Speziell hinzugefügt

Added hat eine besondere Bedingung, sobald eine Entität als markiert ist Added.Alle Entitäten im Diagramm werden als markiert Added auch wenn es sich bei einer Referenzentität um ein vorhandenes Objekt in der Datenbank handelt.Wenn wir diesen Code haben, werden Foo und Bar hinzugefügt.

var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Foo>().Add(foo);
db.SaveChanges();

Um dies zu verhindern, muss zunächst die Stange angebracht werden.

var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Bar>().Attach(bar);
db.Set<Foo>().Add(foo);
db.SaveChanges();

Überprüfen Artikel von Julie Lerman für eine ausführlichere Erklärung.

Der Grund dafür ist, dass bei Verwendung der DBSet.ADD ist auch markiert hinzugefügt.Auch wenn der Entwickler bekannt ist, dass das Thema einen vorhandenen ID -Wert hat, ehrt das Entity Framework seinen EntityState (hinzugefügt) und erstellt unabhängig von der vorhandenen ID einen Befehl zur Datenbankeinfügeeinsatz für das Thema.

Passen Sie die Erklärung basierend auf Ihrem Update an

Und Ihre aktualisierte Frage bezieht sich auf das bestehende Foo und die neue Bar.Wenn Sie Ihren Code verwenden, fügt das Ergebnis kein neues Bar hinzu und das vorhandene Foo stellt keine Beziehung zum neuen Bar her.

var foo = new Foo();
foo.FooId = 524 //Existing foo;

foo.Bar = new Bar(); //Completely new bar    
db.Foos.AddOrUpdate(foo);
db.SaveChanges();

Wenn wir die Bar manuell zusammen mit hinzufügen AddOrUpdate(foo), das Ergebnis ist immer noch nicht wie erwartet.Die neue Bar wird hinzugefügt, aber Foo wird keine Beziehung zur neuen Bar haben.

db.Bars.Add(foo.Bar);
db.Foos.AddOrUpdate(foo);

Das Verhalten von AddOrUpdate ist inkonsistent.

Lösung

Wenn Sie mit nicht verbundenen Objekten arbeiten, müssen Sie die Synchronisation manuell verwalten.

Dieser Code sollte unter allen Bedingungen funktionieren.

  • Neues Foo und neue Bar
  • Neues Foo und bestehende Bar
  • Bestehende Foo und neue Bar
  • Vorhandenes Foo und vorhandene Bar

Dieser Code hängt von der ID ab (id = 0 ist eine neue Entität).

db.Entry(foo).State = 
       foo.FooId == 0 ? EntityState.Added : EntityState.Modified;
if (foo.Bar != null)
{
    db.Entry(foo.Bar).State = 
       foo.Bar.BarId == 0 ? EntityState.Added : EntityState.Modified;
                                                             ^^^
    // If you don't want to change the Bar while creating a relationship between
    // Foo and with existing Bar, you can change 
    // `EntityState.Modified` with `EntityState.Unchanged`
}
db.SaveChanges();

Bezüglich AddOrUpdate, Ich denke, es gibt ein offenes Problem, das gefunden werden kann Hier.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top