Frage DbSet.Attach (Entität) vs DbContext.Entry (Entität) .State = EntityState.Modified


Wenn ich in einem losgelösten Szenario bin und einen Dto vom Client bekomme, den ich in eine Entity mappe, um sie zu speichern, mache ich das:

context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();

Für was dann ist DbSet.Attach(entity)

Oder warum sollte ich die Methode .Attach verwenden, wenn EntityState.Modified die Entität bereits anfügt?


76
2018-06-22 19:03


Ursprung


Antworten:


Wenn Sie das tun context.Entry(entity).State = EntityState.Modified;, Sie fügen nicht nur die Entität an die DbContext, du kennst auch die ganze Entität als schmutzig. Dies bedeutet, dass wenn Sie es tun context.SaveChanges(), EF generiert eine Update-Anweisung, die aktualisiert wird alle die Felder der Entität.

Dies ist nicht immer erwünscht.

Andererseits, DbSet.Attach(entity) hängt die Entität an den Kontext an ohne es schmutzig markieren. Es ist äquivalent zu tun context.Entry(entity).State = EntityState.Unchanged;

Beim Anhängen dieser Methode, es sei denn, Sie aktualisieren dann beim nächsten Aufruf eine Eigenschaft für die Entität context.SaveChanges(), EF wird keine Datenbankaktualisierung für diese Entität generieren.

Selbst wenn Sie eine Aktualisierung für eine Entität planen, wenn die Entität viele Eigenschaften hat (db columns), aber Sie nur einige aktualisieren möchten, könnte es sich als vorteilhaft erweisen, a zu tun DbSet.Attach(entity)und aktualisieren Sie dann nur die wenigen Eigenschaften, die aktualisiert werden müssen. Auf diese Weise wird eine effizientere Update-Anweisung von EF generiert. EF aktualisiert nur die Eigenschaften, die Sie geändert haben (im Gegensatz zu context.Entry(entity).State = EntityState.Modified; wodurch alle Eigenschaften / Spalten aktualisiert werden)

Relevante Dokumentation: Hinzufügen / Anhängen und Entitätsstatus.

Codebeispiel

Nehmen wir an, Sie haben folgende Entität:

public class Person
{
    public int Id { get; set; } // primary key
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Wenn Ihr Code so aussieht:

context.Entry(personEntity).State = EntityState.Modified;
context.SaveChanges();

Das generierte SQL wird ungefähr so ​​aussehen:

UPDATE person
SET FirstName = 'whatever first name is',
    LastName = 'whatever last name is'
WHERE Id = 123; -- whatever Id is.

Beachten Sie, dass die obige update-Anweisung alle Spalten aktualisiert, unabhängig davon, ob Sie die Werte tatsächlich geändert haben oder nicht.

Im Gegensatz dazu, wenn Ihr Code den "normalen" Attach wie folgt verwendet:

context.People.Attach(personEntity); // State = Unchanged
personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty.
context.SaveChanges();

Dann ist die generierte Update-Anweisung anders:

UPDATE person
SET FirstName = 'John'
WHERE Id = 123; -- whatever Id is.

Wie Sie sehen können, die Update-Anweisung nur aktualisiert die Werte, die tatsächlich geändert wurden, nachdem Sie die Entität an den Kontext angefügt haben. Abhängig von der Struktur Ihres Tisches kann sich dies positiv auf die Leistung auswirken.

Welche Option für Sie besser ist, hängt ganz von dem ab, was Sie tun möchten.


184
2018-06-22 19:24



Wenn du das benutzt DbSet.Update Methode markiert Entity Framework alle Eigenschaften Ihrer Entität als EntityState.Modified, so verfolgt sie. Wenn Sie nur einige Ihrer Eigenschaften ändern möchten, verwenden Sie nicht alle DbSet.Attach. Diese Methode macht alle Ihre Eigenschaften EntityState.Unchanged, also müssen Sie Ihre Eigenschaften aktualisieren, die Sie aktualisieren möchten EntityState.Modified. Also wenn die App auf trifft DbContext.SaveChanges, es wird nur modifizierte Eigenschaften betreiben.


0
2017-09-15 07:27