Arbeiten mit Entitäts ZuständenWorking with entity states

In diesem Thema wird das Hinzufügen und Anfügen von Entitäten zu einem Kontext und die Art und Weise beschrieben, wie Entity Framework diese während SaveChanges verarbeitet.This topic will cover how to add and attach entities to a context and how Entity Framework processes these during SaveChanges. Entity Framework übernimmt die Überwachung des Zustands von Entitäten, während Sie mit einem Kontext verbunden sind, aber in getrennten oder N-Tier-Szenarios können Sie EF wissen, in welchem Zustand sich Ihre Entitäten befinden sollten.Entity Framework takes care of tracking the state of entities while they are connected to a context, but in disconnected or N-Tier scenarios you can let EF know what state your entities should be in. Die in diesem Thema dargestellten Techniken gelten jeweils für Modelle, die mit Code First und dem EF-Designer erstellt wurden.The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Entitäts Zustände und SaveChangesEntity states and SaveChanges

Eine Entität kann einen von fünf Zuständen aufweisen, wie von der EntityState-Enumeration definiert.An entity can be in one of five states as defined by the EntityState enumeration. Folgende Status sind möglich:These states are:

  • Hinzugefügt: die Entität wird vom Kontext nachverfolgt, ist aber noch nicht in der Datenbank vorhanden.Added: the entity is being tracked by the context but does not yet exist in the database
  • Unverändert: die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, und die Eigenschaftswerte wurden aus den Werten in der Datenbank nicht geändert.Unchanged: the entity is being tracked by the context and exists in the database, and its property values have not changed from the values in the database
  • Geändert: die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, und einige oder alle Eigenschaftswerte wurden geändert.Modified: the entity is being tracked by the context and exists in the database, and some or all of its property values have been modified
  • Gelöscht: die Entität wird vom Kontext nachverfolgt und ist in der Datenbank vorhanden, wurde aber beim nächsten Aufrufen von SaveChanges zum Löschen aus der Datenbank markiert.Deleted: the entity is being tracked by the context and exists in the database, but has been marked for deletion from the database the next time SaveChanges is called
  • Getrennt: die Entität wird nicht vom Kontext nachverfolgt.Detached: the entity is not being tracked by the context

"SaveChanges" unterscheidet sich für Entitäten in unterschiedlichen Zuständen:SaveChanges does different things for entities in different states:

  • Nicht geänderte Entitäten werden von SaveChanges nicht berührt.Unchanged entities are not touched by SaveChanges. Für Entitäten mit dem Status "unverändert" werden keine Updates an die Datenbank gesendet.Updates are not sent to the database for entities in the Unchanged state.
  • Hinzugefügte Entitäten werden in die Datenbank eingefügt und dann bei Rückgabe von SaveChanges unverändert.Added entities are inserted into the database and then become Unchanged when SaveChanges returns.
  • Geänderte Entitäten werden in der Datenbank aktualisiert und werden bei Rückgabe von SaveChanges unverändert.Modified entities are updated in the database and then become Unchanged when SaveChanges returns.
  • Gelöschte Entitäten werden aus der Datenbank gelöscht und dann vom Kontext getrennt.Deleted entities are deleted from the database and are then detached from the context.

In den folgenden Beispielen wird veranschaulicht, wie der Zustand einer Entität oder eines Entitäts Diagramms geändert werden kann.The following examples show ways in which the state of an entity or an entity graph can be changed.

Hinzufügen einer neuen Entität zum KontextAdding a new entity to the context

Eine neue Entität kann dem Kontext hinzugefügt werden, indem die Add-Methode für dbset aufgerufen wird.A new entity can be added to the context by calling the Add method on DbSet. Dadurch wird die Entität in den hinzugefügten Zustand versetzt, was bedeutet, dass Sie beim nächsten Aufruf von SaveChanges in die Datenbank eingefügt wird.This puts the entity into the Added state, meaning that it will be inserted into the database the next time that SaveChanges is called. Beispiel:For example:

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 Zustand in hinzugefügt zu ändern.Another way to add a new entity to the context is to change its state to Added. Beispiel:For example:

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 verknüpfen, die bereits nachverfolgt wird.Finally, you can add a new entity to the context by hooking it up to another entity that is already being tracked. Dazu kann die neue Entität der Auflistungs Navigations Eigenschaft einer anderen Entität hinzugefügt werden oder indem eine Verweis Navigations Eigenschaft einer anderen Entität festgelegt wird, um auf die neue Entität zu verweisen.This could be by adding the new entity to the collection navigation property of another entity or by setting a reference navigation property of another entity to point to the new entity. Beispiel:For example:

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 aufweist, 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.Note that for all of these examples if the entity being added has references to other entities that are not yet tracked then these new entities will also be added to the context and will be inserted into the database the next time that SaveChanges is called.

Anfügen einer vorhandenen Entität an den KontextAttaching an existing entity to the context

Wenn Sie bereits über eine Entität verfügen, die bereits in der Datenbank vorhanden ist, die aber zurzeit nicht vom Kontext nachverfolgt wird, können Sie den Kontext darüber informieren, dass die Entität mithilfe der Attach-Methode in dbset nachverfolgt wird.If you have an entity that you know already exists in the database but which is not currently being tracked by the context then you can tell the context to track the entity using the Attach method on DbSet. Die Entität befindet sich im Zustand "unverändert" im Kontext.The entity will be in the Unchanged state in the context. Beispiel:For example:

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 keine Änderungen an der Datenbank vorgenommen werden, wenn SaveChanges aufgerufen wird, ohne dass eine andere Bearbeitung der angefügten Entität erfolgt.Note that no changes will be made to the database if SaveChanges is called without doing any other manipulation of the attached entity. Dies liegt daran, dass sich die Entität im unveränderten Zustand befindet.This is because the entity is in the Unchanged state.

Eine andere Möglichkeit, eine vorhandene Entität an den Kontext anzufügen, besteht darin, den Zustand in unverändert zu ändern.Another way to attach an existing entity to the context is to change its state to Unchanged. Beispiel:For example:

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 in beiden Beispielen, wenn die angefügte Entität Verweise auf andere Entitäten enthält, die noch nicht nachverfolgt werden, diese neuen Entitäten ebenfalls im unveränderten Zustand an den Kontext angefügt werden.Note that for both of these examples if the entity being attached has references to other entities that are not yet tracked then these new entities will also attached to the context in the Unchanged state.

Anfügen einer vorhandenen, aber geänderten Entität an den KontextAttaching an existing but modified entity to the context

Wenn Sie bereits über eine Entität verfügen, die bereits in der Datenbank vorhanden ist, für die jedoch möglicherweise Änderungen vorgenommen wurden, können Sie den Kontext anfügen, um die Entität anzufügen und ihren Status auf "geändert" festzulegen.If you have an entity that you know already exists in the database but to which changes may have been made then you can tell the context to attach the entity and set its state to Modified. Beispiel:For example:

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 an die Datenbank gesendet, wenn SaveChanges aufgerufen wird.When you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.

Beachten Sie Folgendes: Wenn die anzufügende Entität Verweise auf andere Entitäten enthält, die noch nicht nachverfolgt werden, werden diese neuen Entitäten im unveränderten Zustand an den Kontext angefügt – Sie werden nicht automatisch geändert.Note that if the entity being attached has references to other entities that are not yet tracked, then these new entities will attached to the context in the Unchanged state—they will not automatically be made Modified. Wenn Sie über mehrere Entitäten verfügen, die als geändert markiert werden müssen, sollten Sie den Status für jede dieser Entitäten einzeln festlegen.If you have multiple entities that need to be marked Modified you should set the state for each of these entities individually.

Ändern des Status einer nach verfolgten EntitätChanging the state of a tracked entity

Sie können den Zustand einer Entität, die bereits nachverfolgt wird, ändern, indem Sie die State-Eigenschaft für Ihren Eintrag festlegen.You can change the state of an entity that is already being tracked by setting the State property on its entry. Beispiel:For example:

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 Add oder Attach für eine Entität, die bereits nachverfolgt ist, auch zum Ändern des Entitäts Zustands verwendet werden kann.Note that calling Add or Attach for an entity that is already tracked can also be used to change the entity state. Wenn z. b. Attach für eine Entität aufgerufen wird, die sich derzeit im hinzugefügten Zustand befindet, ändert sich der Status in unverändert.For example, calling Attach for an entity that is currently in the Added state will change its state to Unchanged.

INSERT-oder Update-MusterInsert or update pattern

Ein gängiges Muster für einige Anwendungen besteht darin, entweder eine Entität als neu hinzuzufügen (was zu einer Daten Bank Einfügung führt) oder eine Entität als vorhanden anzufügen und Sie als geändert (d. h. ein Datenbankupdate) zu kennzeichnen, je nach dem Wert des Primärschlüssels.A common pattern for some applications is to either Add an entity as new (resulting in a database insert) or Attach an entity as existing and mark it as modified (resulting in a database update) depending on the value of the primary key. Wenn z. b. Daten Bank generierte ganzzahlige Primärschlüssel verwendet werden, wird eine Entität mit einem NULL-Schlüssel als neu und eine Entität mit einem Schlüssel ungleich 0 (null) als vorhanden behandelt.For example, when using database generated integer primary keys it is common to treat an entity with a zero key as new and an entity with a non-zero key as existing. Dieses Muster kann erreicht werden, indem der Entitäts Zustand basierend auf einer Überprüfung des Primärschlüssel Werts festgelegt wird.This pattern can be achieved by setting the entity state based on a check of the primary key value. Beispiel:For example:

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 in geändert alle Eigenschaften der Entität als geändert gekennzeichnet werden und alle Eigenschaftswerte an die Datenbank gesendet werden, wenn SaveChanges aufgerufen wird.Note that when you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.