Freigeben über


Arbeiten mit Entitätszuständen

In diesem Thema wird erläutert, wie Sie Entitäten zu einem Kontext hinzufügen und anfügen und wie Entity Framework diese während SaveChanges verarbeitet. Entity Framework kümmert sich um das Nachverfolgen des Status von Entitäten, während sie mit einem Kontext verbunden sind, aber in getrennten oder N-Tier-Szenarien können Sie EF darüber informieren, in welchem Zustand Sich Ihre Entitäten befinden sollen. Die in diesem Thema gezeigten Techniken gelten gleichermaßen für Modelle, die mit Code First und EF Designer erstellt wurden.

Entitätszustände und "SaveChanges"

Eine Entität kann sich in einem von fünf Zuständen befinden, wie durch die EntityState-Aufzählung definiert. Diese Zustände sind:

  • Hinzugefügt: Die Entität wird vom Kontext nachverfolgt, ist aber noch nicht in der Datenbank vorhanden.
  • Unverändert: Die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, und ihre Eigenschaftswerte wurden nicht von den Werten in der Datenbank geändert.
  • Geändert: Die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, und einige oder alle zugehörigen Eigenschaftswerte wurden geändert.
  • Gelöscht: Die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, wurde jedoch für das Löschen aus der Datenbank markiert, wenn SaveChanges das nächste Mal aufgerufen wird.
  • Getrennt: Die Entität wird nicht vom Kontext nachverfolgt.

SaveChanges führt für Entitäten in verschiedenen Zuständen unterschiedliche Aktionen aus:

  • Unveränderte Entitäten werden von SaveChanges nicht berührt. Aktualisierungen werden nicht an die Datenbank für Entitäten im Status "Unverändert" gesendet.
  • Hinzugefügte Entitäten werden in die Datenbank eingefügt und werden dann beim Zurückgeben von SaveChanges unverändert.
  • Geänderte Entitäten werden in der Datenbank aktualisiert und werden dann beim Zurückgeben von SaveChanges unverändert.
  • Gelöschte Entitäten werden aus der Datenbank gelöscht und dann vom Kontext getrennt.

In den folgenden Beispielen wird gezeigt, wie der Status einer Entität oder eines Entitätsdiagramms geändert werden kann.

Hinzufügen einer neuen Entität zum Kontext

Eine neue Entität kann dem Kontext hinzugefügt werden, indem die Add-Methode für DbSet aufgerufen wird. Dadurch wird die Entität in den Status "Hinzugefügt" versetzt, d. h., sie wird beim nächsten Aufruf von SaveChanges in die Datenbank eingefügt. Beispiel:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

Eine weitere Möglichkeit zum Hinzufügen einer neuen Entität zum Kontext besteht darin, den Status in "Hinzugefügt" zu ändern. Beispiel:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Entry(blog).State = EntityState.Added;
    context.SaveChanges();
}

Schließlich können Sie dem Kontext eine neue Entität hinzufügen, indem Sie sie mit einer anderen Entität verbinden, die bereits nachverfolgt wird. Dies kann das Hinzufügen der neuen Entität zur Sammlungsnavigationseigenschaft einer anderen Entität oder das Festlegen einer Referenznavigationseigenschaft einer anderen Entität sein, um auf die neue Entität zu verweisen. Beispiel:

using (var context = new BloggingContext())
{
    // Add a new User by setting a reference from a tracked Blog
    var blog = context.Blogs.Find(1);
    blog.Owner = new User { UserName = "johndoe1987" };

    // Add a new Post by adding to the collection of a tracked Blog
    blog.Posts.Add(new Post { Name = "How to Add Entities" });

    context.SaveChanges();
}

Beachten Sie, dass für alle diese Beispiele, wenn die hinzugefügte Entität Verweise auf andere Entitäten enthält, die noch nicht nachverfolgt werden, diese neuen Entitäten ebenfalls dem Kontext hinzugefügt werden und beim nächsten Aufruf von SaveChanges in die Datenbank eingefügt werden.

Anfügen einer vorhandenen Entität an den Kontext

Wenn Sie über eine Entität verfügen, die Sie bereits in der Datenbank kennen, die aber derzeit nicht vom Kontext nachverfolgt wird, können Sie den Kontext anweisen, die Entität mithilfe der Attach-Methode für DbSet nachzuverfolgen. Die Entität befindet sich im Kontext im Status "Unverändert". Beispiel:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);

    // Do some more work...  

    context.SaveChanges();
}

Beachten Sie, dass an der Datenbank keine Änderungen vorgenommen werden, wenn SaveChanges aufgerufen wird, ohne eine andere Manipulation der angefügten Entität durchzuführen. Dies liegt daran, dass sich die Entität im Zustand "Unverändert" befindet.

Eine weitere Möglichkeit zum Anfügen einer vorhandenen Entität an den Kontext besteht darin, den Status in "Unverändert" zu ändern. Beispiel:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Beachten Sie, dass für beide Beispiele, wenn die angefügte Entität Verweise auf andere Entitäten hat, die noch nicht nachverfolgt werden, diese neuen Entitäten auch dem Kontext im Zustand "Unverändert" zugeordnet werden.

Anfügen einer vorhandenen, aber geänderten Entität an den Kontext

Wenn Sie über eine Entität verfügen, die bereits in der Datenbank vorhanden ist, an der möglicherweise Änderungen vorgenommen wurden, können Sie den Kontext anweisen, die Entität zu verknüpfen und den Status auf "Geändert" festzulegen. Beispiel:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;

    // Do some more work...  

    context.SaveChanges();
}

Wenn Sie den Status in "Geändert" ändern, werden alle Eigenschaften der Entität als geändert markiert, und alle Eigenschaftswerte werden beim Aufrufen von SaveChanges an die Datenbank gesendet.

Beachten Sie, dass, wenn die angefügte Entität Verweise auf andere Entitäten enthält, die noch nicht nachverfolgt werden, diese neuen Entitäten dem Kontext im Zustand "Unverändert" angefügt werden– sie werden nicht automatisch geändert. Wenn Sie über mehrere Entitäten verfügen, die als "Geändert" gekennzeichnet werden müssen, sollten Sie den Status für jede dieser Entitäten einzeln festlegen.

Ändern des Status einer nachverfolgten Entität

Sie können den Status einer Entität ändern, die bereits nachverfolgt wird, indem Sie die Statuseigenschaft für den Eintrag festlegen. Beispiel:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Beachten Sie, dass das Aufrufen von "Hinzufügen" oder "Anfügen" für eine bereits nachverfolgte Entität auch verwendet werden kann, um den Entitätsstatus zu ändern. Wenn Sie beispielsweise "Anfügen" für eine Entität aufrufen, die sich derzeit im Zustand "Hinzugefügt" befindet, wird der Status in "Unverändert" geändert.

Einfügen oder Aktualisieren des Musters

Ein gängiges Muster für einige Anwendungen besteht darin, entweder eine Entität als neu hinzuzufügen (was zu einem Datenbankeinfügung führt) oder eine Entität als vorhanden anzufügen und sie je nach Wert des Primärschlüssels als geändert zu markieren (was zu einer Datenbankaktualisierung führt). Wenn Sie beispielsweise datenbankgenerierte ganzzahlige Primärschlüssel verwenden, ist es üblich, eine Entität mit einem Nullschlüssel als neu zu behandeln und eine Entität mit einem Nicht-Null-Schlüssel als vorhanden zu behandeln. Dieses Muster kann erreicht werden, indem der Entitätsstatus basierend auf einer Überprüfung des Primärschlüsselwerts festgelegt wird. Beispiel:

public void InsertOrUpdate(Blog blog)
{
    using (var context = new BloggingContext())
    {
        context.Entry(blog).State = blog.BlogId == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;

        context.SaveChanges();
    }
}

Beachten Sie, dass beim Ändern des Zustands "Geändert" alle Eigenschaften der Entität als geändert markiert werden, und alle Eigenschaftswerte werden beim Aufrufen von SaveChanges an die Datenbank gesendet.