Arbeiten mit Eigenschafts WertenWorking with property values

In den meisten Fällen übernimmt Entity Framework die Nachverfolgung des Zustands, der ursprünglichen Werte und der aktuellen Werte der Eigenschaften der Entitäts Instanzen.For the most part Entity Framework will take care of tracking the state, original values, and current values of the properties of your entity instances. Es gibt jedoch einige Fälle, z. b. getrennte Szenarios, in denen Sie die Informationen anzeigen oder bearbeiten möchten, die EF über die Eigenschaften verfügt.However, there may be some cases - such as disconnected scenarios - where you want to view or manipulate the information EF has about the properties. 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.

Entity Framework verfolgt zwei Werte für jede Eigenschaft einer nach verfolgten Entität nach.Entity Framework keeps track of two values for each property of a tracked entity. Der aktuelle Wert ist, wie der Name zeigt, der aktuelle Wert der-Eigenschaft in der Entität.The current value is, as the name indicates, the current value of the property in the entity. Der ursprüngliche Wert ist der Wert, den die Eigenschaft hatte, als die Entität von der Datenbank abgefragt oder an den Kontext angefügt wurde.The original value is the value that the property had when the entity was queried from the database or attached to the context.

Es gibt zwei allgemeine Mechanismen zum Arbeiten mit Eigenschafts Werten:There are two general mechanisms for working with property values:

  • Der Wert einer einzelnen Eigenschaft kann mithilfe der-Eigenschaften Methode in einer stark typisierten Weise abgerufen werden.The value of a single property can be obtained in a strongly typed way using the Property method.
  • Werte für alle Eigenschaften einer Entität können in ein dbpropertyvalues-Objekt eingelesen werden.Values for all properties of an entity can be read into a DbPropertyValues object. Dbpropertyvalues fungiert dann als Wörterbuch ähnliches Objekt, um das Lesen und Festlegen von Eigenschafts Werten zuzulassen.DbPropertyValues then acts as a dictionary-like object to allow property values to be read and set. Die Werte in einem dbpropertyvalues-Objekt können aus Werten in einem anderen dbpropertyvalues-Objekt oder aus Werten in einem anderen Objekt, z. b. einer anderen Kopie der Entität oder einem einfachen Datenübertragungs Objekt (Data Transfer Object, dto), festgelegt werden.The values in a DbPropertyValues object can be set from values in another DbPropertyValues object or from values in some other object, such as another copy of the entity or a simple data transfer object (DTO).

In den folgenden Abschnitten sind Beispiele für die Verwendung der beiden oben genannten Mechanismen aufgeführt.The sections below show examples of using both of the above mechanisms.

Festlegen und Festlegen des aktuellen oder ursprünglichen Werts einer einzelnen EigenschaftGetting and setting the current or original value of an individual property

Im folgenden Beispiel wird gezeigt, wie der aktuelle Wert einer Eigenschaft gelesen und dann auf einen neuen Wert festgelegt werden kann:The example below shows how the current value of a property can be read and then set to a new value:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(3);

    // Read the current value of the Name property
    string currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue;

    // Set the Name property to a new value
    context.Entry(blog).Property(u => u.Name).CurrentValue = "My Fancy Blog";

    // Read the current value of the Name property using a string for the property name
    object currentName2 = context.Entry(blog).Property("Name").CurrentValue;

    // Set the Name property to a new value using a string for the property name
    context.Entry(blog).Property("Name").CurrentValue = "My Boring Blog";
}

Verwenden Sie die Eigenschaft OriginalValue anstelle der Eigenschaft CurrentValue, um den ursprünglichen Wert zu lesen oder festzulegen.Use the OriginalValue property instead of the CurrentValue property to read or set the original value.

Beachten Sie, dass der zurückgegebene Wert als "Object" typisiert wird, wenn eine Zeichenfolge verwendet wird, um den Namen der Eigenschaft anzugeben.Note that the returned value is typed as “object” when a string is used to specify the property name. Auf der anderen Seite ist der zurückgegebene Wert stark typisiert, wenn ein Lambda-Ausdruck verwendet wird.On the other hand, the returned value is strongly typed if a lambda expression is used.

Wenn Sie den Eigenschafts Wert auf diese Weise festlegen, wird die Eigenschaft nur als geändert markiert, wenn der neue Wert vom alten Wert abweicht.Setting the property value like this will only mark the property as modified if the new value is different from the old value.

Wenn ein Eigenschafts Wert auf diese Weise festgelegt wird, wird die Änderung automatisch erkannt, auch wenn autodetectchanges deaktiviert ist.When a property value is set in this way the change is automatically detected even if AutoDetectChanges is turned off.

Der aktuelle Wert einer nicht zugeordneten Eigenschaft wird erhalten und festgelegt.Getting and setting the current value of an unmapped property

Der aktuelle Wert einer Eigenschaft, die nicht der Datenbank zugeordnet ist, kann ebenfalls gelesen werden.The current value of a property that is not mapped to the database can also be read. Ein Beispiel für eine nicht zugeordnete Eigenschaft könnte eine rsslink-Eigenschaft im Blog sein.An example of an unmapped property could be an RssLink property on Blog. Dieser Wert kann basierend auf der BlogId berechnet werden und muss daher nicht in der Datenbank gespeichert werden.This value may be calculated based on the BlogId, and therefore doesn't need to be stored in the database. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    // Read the current value of an unmapped property
    var rssLink = context.Entry(blog).Property(p => p.RssLink).CurrentValue;

    // Use a string to specify the property name
    var rssLinkAgain = context.Entry(blog).Property("RssLink").CurrentValue;
}

Der aktuelle Wert kann auch festgelegt werden, wenn die-Eigenschaft einen Setter verfügbar macht.The current value can also be set if the property exposes a setter.

Das Lesen der Werte nicht zugeordneter Eigenschaften ist nützlich, wenn Entity Framework Überprüfung nicht zugeordneter Eigenschaften durchgeführt wird.Reading the values of unmapped properties is useful when performing Entity Framework validation of unmapped properties. Aus demselben Grund können aktuelle Werte gelesen und für Eigenschaften von Entitäten festgelegt werden, die derzeit nicht durch den Kontext verfolgt werden.For the same reason current values can be read and set for properties of entities that are not currently being tracked by the context. Beispiel:For example:

using (var context = new BloggingContext())
{
    // Create an entity that is not being tracked
    var blog = new Blog { Name = "ADO.NET Blog" };

    // Read and set the current value of Name as before
    var currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue;
    context.Entry(blog).Property(u => u.Name).CurrentValue = "My Fancy Blog";
    var currentName2 = context.Entry(blog).Property("Name").CurrentValue;
    context.Entry(blog).Property("Name").CurrentValue = "My Boring Blog";
}

Beachten Sie, dass die ursprünglichen Werte für nicht zugeordnete Eigenschaften oder für Eigenschaften von Entitäten, die nicht vom Kontext nachverfolgt werden, nicht verfügbar sind.Note that original values are not available for unmapped properties or for properties of entities that are not being tracked by the context.

Es wird überprüft, ob eine Eigenschaft als geändert markiert ist.Checking whether a property is marked as modified

Im folgenden Beispiel wird gezeigt, wie Sie überprüfen können, ob eine einzelne Eigenschaft als geändert gekennzeichnet ist:The example below shows how to check whether or not an individual property is marked as modified:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var nameIsModified1 = context.Entry(blog).Property(u => u.Name).IsModified;

    // Use a string for the property name
    var nameIsModified2 = context.Entry(blog).Property("Name").IsModified;
}

Die Werte der geänderten Eigenschaften werden als Aktualisierungen an die Datenbank gesendet, wenn SaveChanges aufgerufen wird.The values of modified properties are sent as updates to the database when SaveChanges is called.

Markieren einer Eigenschaft als geändertMarking a property as modified

Das folgende Beispiel zeigt, wie Sie erzwingen können, dass eine einzelne Eigenschaft als geändert markiert wird:The example below shows how to force an individual property to be marked as modified:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    context.Entry(blog).Property(u => u.Name).IsModified = true;

    // Use a string for the property name
    context.Entry(blog).Property("Name").IsModified = true;
}

Wenn eine Eigenschaft als geändert markiert wird, wird ein Update für die-Eigenschaft an die Datenbank gesendet, wenn SaveChanges aufgerufen wird, auch wenn der aktuelle Wert der-Eigenschaft mit dem ursprünglichen Wert übereinstimmt.Marking a property as modified forces an update to be send to the database for the property when SaveChanges is called even if the current value of the property is the same as its original value.

Es ist derzeit nicht möglich, eine einzelne Eigenschaft zurückzusetzen, sodass Sie nicht geändert wird, nachdem Sie als geändert markiert wurde.It is not currently possible to reset an individual property to be not modified after it has been marked as modified. Dies wird in einer zukünftigen Version unterstützt.This is something we plan to support in a future release.

Lesen aktueller, ursprünglicher und Daten Bankwerte für alle Eigenschaften einer EntitätReading current, original, and database values for all properties of an entity

Das folgende Beispiel zeigt, wie die aktuellen Werte, die ursprünglichen Werte und die Werte in der Datenbank für alle zugeordneten Eigenschaften einer Entität gelesen werden.The example below shows how to read the current values, the original values, and the values actually in the database for all mapped properties of an entity.

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Make a modification to Name in the tracked entity
    blog.Name = "My Cool Blog";

    // Make a modification to Name in the database
    context.Database.SqlCommand("update dbo.Blogs set Name = 'My Boring Blog' where Id = 1");

    // Print out current, original, and database values
    Console.WriteLine("Current values:");
    PrintValues(context.Entry(blog).CurrentValues);

    Console.WriteLine("\nOriginal values:");
    PrintValues(context.Entry(blog).OriginalValues);

    Console.WriteLine("\nDatabase values:");
    PrintValues(context.Entry(blog).GetDatabaseValues());
}

public static void PrintValues(DbPropertyValues values)
{
    foreach (var propertyName in values.PropertyNames)
    {
        Console.WriteLine("Property {0} has value {1}",
                          propertyName, values[propertyName]);
    }
}

Die aktuellen Werte sind die Werte, die die Eigenschaften der Entität derzeit enthalten.The current values are the values that the properties of the entity currently contain. Bei den ursprünglichen Werten handelt es sich um die Werte, die aus der Datenbank gelesen wurden, als die Entität abgefragt wurde.The original values are the values that were read from the database when the entity was queried. Bei den Daten bankwerten handelt es sich um die Werte, die aktuell in der Datenbank gespeichert sind.The database values are the values as they are currently stored in the database. Das übertragen der Daten Bankwerte ist hilfreich, wenn sich die Werte in der Datenbank möglicherweise seit der Abfrage der Entität geändert haben, z. b. Wenn ein anderer Benutzer eine gleichzeitige Bearbeitung der Datenbank durchgeführt hat.Getting the database values is useful when the values in the database may have changed since the entity was queried such as when a concurrent edit to the database has been made by another user.

Festlegen aktueller oder ursprünglicher Werte aus einem anderen ObjektSetting current or original values from another object

Die aktuellen oder ursprünglichen Werte einer nach verfolgten Entität können aktualisiert werden, indem Werte aus einem anderen Objekt kopiert werden.The current or original values of a tracked entity can be updated by copying values from another object. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    var coolBlog = new Blog { Id = 1, Name = "My Cool Blog" };
    var boringBlog = new BlogDto { Id = 1, Name = "My Boring Blog" };

    // Change the current and original values by copying the values from other objects
    var entry = context.Entry(blog);
    entry.CurrentValues.SetValues(coolBlog);
    entry.OriginalValues.SetValues(boringBlog);

    // Print out current and original values
    Console.WriteLine("Current values:");
    PrintValues(entry.CurrentValues);

    Console.WriteLine("\nOriginal values:");
    PrintValues(entry.OriginalValues);
}

public class BlogDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Wenn Sie den obigen Code ausführen, wird Folgendes gedruckt:Running the code above will print out:

Current values:
Property Id has value 1
Property Name has value My Cool Blog

Original values:
Property Id has value 1
Property Name has value My Boring Blog

Diese Technik wird manchmal beim Aktualisieren einer Entität mit Werten verwendet, die von einem Dienst-oder Client in einer n-Tier-Anwendung abgerufen werden.This technique is sometimes used when updating an entity with values obtained from a service call or a client in an n-tier application. Beachten Sie, dass das verwendete Objekt nicht denselben Typ wie die Entität aufweisen muss, solange es über Eigenschaften verfügt, deren Namen mit denen der Entität übereinstimmen.Note that the object used does not have to be of the same type as the entity so long as it has properties whose names match those of the entity. Im obigen Beispiel wird eine Instanz von blogdto verwendet, um die ursprünglichen Werte zu aktualisieren.In the example above, an instance of BlogDTO is used to update the original values.

Beachten Sie, dass nur Eigenschaften, die auf verschiedene Werte festgelegt sind, wenn Sie aus dem anderen Objekt kopiert werden, als geändert gekennzeichnet werden.Note that only properties that are set to different values when copied from the other object will be marked as modified.

Festlegen aktueller oder ursprünglicher Werte aus einem WörterbuchSetting current or original values from a dictionary

Die aktuellen oder ursprünglichen Werte einer nach verfolgten Entität können aktualisiert werden, indem Werte aus einem Wörterbuch oder einer anderen Datenstruktur kopiert werden.The current or original values of a tracked entity can be updated by copying values from a dictionary or some other data structure. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var newValues = new Dictionary<string, object>
    {
        { "Name", "The New ADO.NET Blog" },
        { "Url", "blogs.msdn.com/adonet" },
    };

    var currentValues = context.Entry(blog).CurrentValues;

    foreach (var propertyName in newValues.Keys)
    {
        currentValues[propertyName] = newValues[propertyName];
    }

    PrintValues(currentValues);
}

Verwenden Sie die OriginalValues-Eigenschaft anstelle der CurrentValues-Eigenschaft, um die ursprünglichen Werte festzulegen.Use the OriginalValues property instead of the CurrentValues property to set original values.

Festlegen aktueller oder ursprünglicher Werte aus einem Wörterbuch mithilfe der-EigenschaftSetting current or original values from a dictionary using Property

Eine Alternative zur Verwendung von CurrentValues oder OriginalValues, wie oben gezeigt, besteht darin, die-Eigenschaften Methode zum Festlegen des Werts der einzelnen Eigenschaften zu verwenden.An alternative to using CurrentValues or OriginalValues as shown above is to use the Property method to set the value of each property. Dies ist vorzuziehen, wenn Sie die Werte komplexer Eigenschaften festlegen müssen.This can be preferable when you need to set the values of complex properties. Beispiel:For example:

using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    var newValues = new Dictionary<string, object>
    {
        { "Name", "John Doe" },
        { "Location.City", "Redmond" },
        { "Location.State.Name", "Washington" },
        { "Location.State.Code", "WA" },
    };

    var entry = context.Entry(user);

    foreach (var propertyName in newValues.Keys)
    {
        entry.Property(propertyName).CurrentValue = newValues[propertyName];
    }
}

Im obigen Beispiel erfolgt der Zugriff auf komplexe Eigenschaften mithilfe von punktierten Namen.In the example above complex properties are accessed using dotted names. Weitere Möglichkeiten, um auf komplexe Eigenschaften zuzugreifen, finden Sie in den beiden Abschnitten weiter unten in diesem Thema speziell zu komplexen Eigenschaften.For other ways to access complex properties see the two sections later in this topic specifically about complex properties.

Erstellen eines geklonten Objekts mit aktuellen, ursprünglichen oder Daten bankwertenCreating a cloned object containing current, original, or database values

Das von CurrentValues, OriginalValues oder getdatabasevalues zurückgegebene dbpropertyvalues-Objekt kann verwendet werden, um einen Klon der Entität zu erstellen.The DbPropertyValues object returned from CurrentValues, OriginalValues, or GetDatabaseValues can be used to create a clone of the entity. Dieser Klon enthält die Eigenschaftswerte aus dem dbpropertyvalues-Objekt, das zur Erstellung verwendet wird.This clone will contain the property values from the DbPropertyValues object used to create it. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var clonedBlog = context.Entry(blog).GetDatabaseValues().ToObject();
}

Beachten Sie, dass das zurückgegebene Objekt nicht die Entität ist und nicht vom Kontext nachverfolgt wird.Note that the object returned is not the entity and is not being tracked by the context. Für das zurückgegebene Objekt sind auch keine Beziehungen auf andere Objekte festgelegt.The returned object also does not have any relationships set to other objects.

Das geklonte Objekt kann nützlich sein, um Probleme im Zusammenhang mit gleichzeitigen Aktualisierungen der Datenbank zu beheben. Dies gilt insbesondere, wenn eine Benutzeroberfläche verwendet wird, die eine Datenbindung an Objekte eines bestimmten Typs einschließt.The cloned object can be useful for resolving issues related to concurrent updates to the database, especially where a UI that involves data binding to objects of a certain type is being used.

Erhalten und Festlegen der aktuellen oder ursprünglichen Werte komplexer EigenschaftenGetting and setting the current or original values of complex properties

Der Wert eines gesamten komplexen Objekts kann mithilfe der-Eigenschaften Methode gelesen und festgelegt werden, so wie es für eine primitive Eigenschaft möglich ist.The value of an entire complex object can be read and set using the Property method just as it can be for a primitive property. Außerdem können Sie einen Drilldown in das komplexe Objekt durchführen und die Eigenschaften des Objekts oder sogar ein geschieetes Objekt lesen oder festlegen.In addition you can drill down into the complex object and read or set properties of that object, or even a nested object. Hier einige Beispiele:Here are some examples:

using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    // Get the Location complex object
    var location = context.Entry(user)
                       .Property(u => u.Location)
                       .CurrentValue;

    // Get the nested State complex object using chained calls
    var state1 = context.Entry(user)
                     .ComplexProperty(u => u.Location)
                     .Property(l => l.State)
                     .CurrentValue;

    // Get the nested State complex object using a single lambda expression
    var state2 = context.Entry(user)
                     .Property(u => u.Location.State)
                     .CurrentValue;

    // Get the nested State complex object using a dotted string
    var state3 = context.Entry(user)
                     .Property("Location.State")
                     .CurrentValue;

    // Get the value of the Name property on the nested State complex object using chained calls
    var name1 = context.Entry(user)
                       .ComplexProperty(u => u.Location)
                       .ComplexProperty(l => l.State)
                       .Property(s => s.Name)
                       .CurrentValue;

    // Get the value of the Name property on the nested State complex object using a single lambda expression
    var name2 = context.Entry(user)
                       .Property(u => u.Location.State.Name)
                       .CurrentValue;

    // Get the value of the Name property on the nested State complex object using a dotted string
    var name3 = context.Entry(user)
                       .Property("Location.State.Name")
                       .CurrentValue;
}

Verwenden Sie die OriginalValue-Eigenschaft anstelle der CurrentValue-Eigenschaft, um einen ursprünglichen Wert zu erhalten oder festzulegen.Use the OriginalValue property instead of the CurrentValue property to get or set an original value.

Beachten Sie, dass entweder die-Eigenschaft oder die ComplexProperty-Methode für den Zugriff auf eine komplexe Eigenschaft verwendet werden kann.Note that either the Property or the ComplexProperty method can be used to access a complex property. Allerdings muss die ComplexProperty-Methode verwendet werden, wenn Sie einen Drilldown in das komplexe Objekt mit zusätzlichen Eigenschafts-oder ComplexProperty-aufrufen durchführen möchten.However, the ComplexProperty method must be used if you wish to drill down into the complex object with additional Property or ComplexProperty calls.

Verwenden von dbpropertyvalues zum Zugreifen auf komplexe EigenschaftenUsing DbPropertyValues to access complex properties

Wenn Sie "CurrentValues", "OriginalValues" oder "getdatabasevalues" verwenden, um alle aktuellen, ursprünglichen oder Daten Bankwerte für eine Entität zu erhalten, werden die Werte aller komplexen Eigenschaften als geduckte dbpropertyvalues-Objekte zurückgegeben.When you use CurrentValues, OriginalValues, or GetDatabaseValues to get all the current, original, or database values for an entity, the values of any complex properties are returned as nested DbPropertyValues objects. Diese-Objekte können dann verwendet werden, um Werte für das komplexe Objekt zu erhalten.These nested objects can then be used to get values of the complex object. Mit der folgenden Methode werden z. b. die Werte aller Eigenschaften gedruckt, einschließlich der Werte aller komplexen Eigenschaften und der in der Tabelle komplexen komplexen Eigenschaften.For example, the following method will print out the values of all properties, including values of any complex properties and nested complex properties.

public static void WritePropertyValues(string parentPropertyName, DbPropertyValues propertyValues)
{
    foreach (var propertyName in propertyValues.PropertyNames)
    {
        var nestedValues = propertyValues[propertyName] as DbPropertyValues;
        if (nestedValues != null)
        {
            WritePropertyValues(parentPropertyName + propertyName + ".", nestedValues);
        }
        else
        {
            Console.WriteLine("Property {0}{1} has value {2}",
                              parentPropertyName, propertyName,
                              propertyValues[propertyName]);
        }
    }
}

Um alle aktuellen Eigenschaftswerte auszugeben, wird die-Methode wie folgt aufgerufen:To print out all current property values the method would be called like this:

using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    WritePropertyValues("", context.Entry(user).CurrentValues);
}