Share via


Melden von Änderungen in benutzerdefinierten Datenklassen (Entity Framework)

Object Services stellt die IEntityChangeTracker-Schnittstelle bereit, mit der Datenklassen an Dateneigenschaften durchgeführte Änderungen melden. EntityObject implementiert die SetChangeTracker-Methode von IEntityWithChangeTracker. Diese Methode wird von Object Services aufgerufen, um die Instanz von IEntityChangeTracker anzugeben, mit der ein Objekt Änderungen meldet. Das von IEntityChangeTracker unterstützte Berichtsmodell für Änderungen ermöglicht, eine ausstehende Änderung an einer Eigenschaft zu melden, die Eigenschaft festzulegen und anschließend zu melden, dass die Änderung abgeschlossen ist.

Damit benutzerdefinierte Datenklassen, die nicht von EntityObject erben, Änderungen melden können, müssen diese Klassen IEntityWithChangeTracker implementieren. Weitere Informationen finden Sie unter Implementieren von Schnittstellen für benutzerdefinierte Datenklassen (Entity Framework).

Folgendes gilt beim Melden von Änderungen:

  • Bevor Sie den Wert einer Eigenschaft festlegen, sollten Sie die Eigenschaft als zu ändern melden. Nachdem Sie den Wert der Eigenschaft festgelegt haben, sollten Sie die Eigenschaft als geändert melden.

  • Sie müssen Änderungen an der EntityKey-Eigenschaft melden. Nach dem Festlegen der EntityKey-Eigenschaft wird vom Anwendungscode, der diese Eigenschaft als zu ändern meldet, eine InvalidOperationException ausgelöst. In einigen Fällen muss Object Services die EntityKey-Eigenschaft jedoch ändern können, nachdem sie festgelegt wurde. Durch das Melden von Änderungen an dieser Eigenschaft kann Object Services ermitteln, wann diese Eigenschaft festzulegen ist.

  • Sie können eine Eigenschaft als zu ändern melden, ohne anschließend zu melden, dass sie geändert wurde. Allerdings wird die Änderung in diesem Fall nicht protokolliert.

  • Es wird eine InvalidOperationException ausgelöst, wenn Sie eine Eigenschaft als geändert melden, bevor Sie dieselbe Eigenschaft als zu ändern melden, oder wenn ein ungültiger Eigenschaftenname übergeben wird. Dies kann der Fall sein, wenn mehrere Eigenschaften als zu ändern gemeldet werden, ohne sie später als geändert zu melden. Dies liegt daran, dass beim Überprüfen der geänderten Eigenschaft anhand der Eigenschaft, die zuerst als zu ändern gemeldet wurde, nur die letzte Eigenschaft erkannt wird.

Melden von Eigenschaftenänderungen beim Erben von EntityObject und ComplexObject

Wenn eine benutzerdefinierte Datenklasse von EntityObject oder ComplexObject erbt, müssen Sie die ReportPropertyChanging-Methode und die ReportPropertyChanged-Methode aufrufen, um die Eigenschaftenänderungen zu melden.

So melden Sie Änderungen an einer Eigenschaft beim Erben von EntityObject

  1. Rufen Sie die System.Data.Objects.DataClasses.EntityObject.ReportPropertyChanging(System.String)-Methode für EntityObject auf, und übergeben Sie den Namen der zu ändernden Eigenschaft.

    Dadurch wird der aktuelle Wert der Eigenschaft zwischengespeichert. Dieser Wert wird als der ursprüngliche Wert der Eigenschaft verwendet.

  2. Legen Sie die Eigenschaft entsprechend fest.

  3. Rufen Sie die System.Data.Objects.DataClasses.EntityObject.ReportPropertyChanged(System.String)-Methode für EntityObject auf, und übergeben Sie den Namen der geänderten Eigenschaft.

    Dadurch wird Object Services benachrichtigt, dass die ausstehende Änderung der Eigenschaft jetzt abgeschlossen ist, und die Eigenschaft wird von Object Services als geändert gekennzeichnet.

So melden Sie Änderungen an einer Eigenschaft beim Erben von ComplexObject

  1. Rufen Sie die System.Data.Objects.DataClasses.ComplexObject.ReportPropertyChanging(System.String)-Methode für ComplexObject auf, und übergeben Sie den Namen der zu ändernden Eigenschaft. Dadurch wird der aktuelle Wert der Eigenschaft zwischengespeichert. Dieser Wert wird als der ursprüngliche Wert der Eigenschaft verwendet.

  2. Legen Sie die Eigenschaft entsprechend fest.

  3. Rufen Sie die System.Data.Objects.DataClasses.ComplexObject.ReportPropertyChanged(System.String)-Methode für ComplexObject auf, und übergeben Sie den Namen der geänderten Eigenschaft. Dadurch wird Object Services benachrichtigt, dass die ausstehende Änderung der Eigenschaft jetzt abgeschlossen ist, und die Eigenschaft wird von Object Services als geändert gekennzeichnet.

Im folgenden Beispiel wird gezeigt, wie Änderungen beim Festlegen der Status-Skalareigenschaft des Order-Objekts gemeldet werden können:

<EdmScalarPropertyAttribute(IsNullable:=False)> _
Public Property Status() As Byte
    Get
        Return _status
    End Get
    Set(ByVal value As Byte)
        If _status <> value Then
            ReportPropertyChanging("Status")
            _status = value
            ReportPropertyChanged("Status")
        End If
    End Set
End Property
[EdmScalarPropertyAttribute(IsNullable = false)]
public byte Status
{
    get 
    {
        return _status;
    }
    set
    {
        if (_status != value)
        {
            ReportPropertyChanging("Status");
            _status = value;
            ReportPropertyChanged("Status");
        }
    }
}

Melden von Eigenschaftsänderungen beim Implementieren von IEntityWithChangeTracker

Wenn eine benutzerdefinierte Datenklasse IEntityWithChangeTracker implementiert, müssen Sie vor und nach dem Ändern der Eigenschaft Änderungsberichtsmethoden für IEntityChangeTracker aufrufen, um die Änderung ordnungsgemäß zu melden.

So melden Sie Änderungen an einer Eigenschaft beim Implementieren von IEntityWithChangeTracker

  1. Rufen Sie die EntityMemberChanging-Methode auf, und übergeben Sie den Namen der zu ändernden Eigenschaft. Dadurch wird der aktuelle Wert der Eigenschaft zwischengespeichert. Dieser Wert wird als der ursprüngliche Wert der Eigenschaft verwendet.

  2. Legen Sie die Eigenschaft entsprechend fest.

  3. Rufen Sie die EntityMemberChanged-Methode auf, und übergeben Sie den Namen der geänderten Eigenschaft.

  4. Dadurch wird Object Services benachrichtigt, dass die ausstehende Änderung der Eigenschaft jetzt abgeschlossen ist, und die Eigenschaft wird von Object Services als geändert gekennzeichnet.

So melden Sie Änderungen an einer Eigenschaft beim Implementieren von IEntityWithChangeTracker für einen komplexen Typ

  1. Rufen Sie die EntityComplexMemberChanging-Methode auf, und übergeben Sie den Namen der geänderten Entitätseigenschaft der obersten Ebene, die Instanz des komplexen Objekts, die die geänderte Eigenschaft enthält, und den Namen der Eigenschaft, die in einen komplexen Typ geändert wurde. Dadurch wird der aktuelle Wert der Eigenschaft zwischengespeichert. Dieser Wert wird als der ursprüngliche Wert der Eigenschaft verwendet.

  2. Legen Sie die Eigenschaft entsprechend fest.

  3. Rufen Sie die EntityComplexMemberChanged-Methode auf, und übergeben Sie den Namen der geänderten Entitätseigenschaft der obersten Ebene, die Instanz des komplexen Objekts, die die geänderte Eigenschaft enthält, und den Namen der Eigenschaft, die in einen komplexen Typ geändert wurde. Dadurch wird Object Services benachrichtigt, dass die ausstehende Änderung der Eigenschaft jetzt abgeschlossen ist, und die Eigenschaft wird von Object Services als geändert gekennzeichnet.

Manchmal ist möglicherweise keine Instanz von IEntityChangeTracker verfügbar. Dies kann geschehen, wenn ein Objekt vom Objektkontext getrennt oder eine Abfrage mit der NoTracking-Option ausgeführt wird. Sie müssen überprüfen, ob eine Instanz von IEntityChangeTracker vorhanden ist, bevor Sie die Änderungsberichtsmethoden aufrufen.

Im folgenden Beispiel wird die abstrakte Klasse ComplexTypeChangeTracker dargestellt, die als Basisklasse für alle abgeleiteten komplexen Typen verwendet wird. Diese Klasse implementiert die Änderungsnachverfolgung für komplexe Typen.

' Base class for complex types that implements change tracking.
Public MustInherit Class ComplexTypeChangeTracker
    Protected _complexChangeTracker As IEntityChangeTracker = Nothing
    Private _rootComplexPropertyName As String

    ' Gets an IEntityChangeTracker to call for properties change. 
    ' You must do this in order to track changes.
    Public Overridable Sub SetComplexChangeTracker( _
        ByVal rootComplexPropertyName As String, _
        ByVal complexChangeTracker As IEntityChangeTracker)
        _rootComplexPropertyName = rootComplexPropertyName
        _complexChangeTracker = complexChangeTracker
    End Sub

    ' Protected method that is called before the change for change tracking 
    ' each of the scalar properties in the complex type.
    Protected Sub ReportMemberChanging(ByVal scalarPropertyName As String)
        If Not _complexChangeTracker Is Nothing Then
            _complexChangeTracker.EntityComplexMemberChanging( _
                _rootComplexPropertyName, Me, scalarPropertyName)
        End If
    End Sub

    ' Protected method that is called after the change for change tracking 
    ' each of the scalar properties in the complex type.
    Protected Sub ReportMemberChanged(ByVal scalarPropertyName As String)
        If Not _complexChangeTracker Is Nothing Then
            _complexChangeTracker.EntityComplexMemberChanged( _
                _rootComplexPropertyName, Me, scalarPropertyName)
        End If
    End Sub
End Class
// Base class for complex types that implements change tracking.
public abstract class ComplexTypeChangeTracker
{
    protected IEntityChangeTracker _complexChangeTracker = null;
    private string _rootComplexPropertyName;

    // Gets an IEntityChangeTracker to call for properties change. 
    // You must do this in order to track changes.
    virtual public void SetComplexChangeTracker(string rootComplexPropertyName, IEntityChangeTracker complexChangeTracker)
    {
        _rootComplexPropertyName = rootComplexPropertyName;
        _complexChangeTracker = complexChangeTracker;
    }

    // Protected method that is called before the change for change tracking 
    // each of the scalar properties in the complex type.
    protected void ReportMemberChanging(string scalarPropertyName)
    {
        if (null != _complexChangeTracker)
        {
            _complexChangeTracker.EntityComplexMemberChanging(_rootComplexPropertyName,
                                                       this, scalarPropertyName);
        }
    }

    // Protected method that is called after the change for change tracking 
    // each of the scalar properties in the complex type.
    protected void ReportMemberChanged(string scalarPropertyName)
    {
        if (null != _complexChangeTracker)
        {
            _complexChangeTracker.EntityComplexMemberChanged(_rootComplexPropertyName,
                                                      this, scalarPropertyName);
        }
    }
}

Im folgenden Beispiel wird gezeigt, wie die Methoden des vorherigen Beispiels verwendet werden, um Änderungen beim Festlegen der skalaren Status-Eigenschaft des Order-Objekts zu melden:

<EdmScalarPropertyAttribute()> _
Public Property Comment() As String
    Get
        Return _comment
    End Get
    Set(ByVal value As String)
        ' Validate the value before setting it.
        If (value <> Nothing) AndAlso value.Length > 128 Then
            Throw New ApplicationException(String.Format( _
                      My.Resources.propertyNotValidString, _
                      "Comment", "128"))
        End If
        If _comment <> value Then
            ' Report the change if the change tracker exists.
            If Not _complexChangeTracker Is Nothing Then
                ReportMemberChanging("Comment")
                _comment = value
                ReportMemberChanged("Comment")
            Else
                _comment = value
            End If
        End If
    End Set
End Property
[EdmScalarPropertyAttribute()]
public string Comment
{
    get
    {
        return _comment;
    }
    set
    {
        // Validate the value before setting it.
        if ((value != null) && value.Length > 128)
        {
            throw new ApplicationException(string.Format(
                      Properties.Resources.propertyNotValidString,
                      new string[3] { value, "Comment", "128" }));
        }
        if (_comment != value)
        {
            // Report the change if the change tracker exists.
            if (_complexChangeTracker != null)
            {
                ReportMemberChanging("Comment");
                _comment = value;
                ReportMemberChanged("Comment");
            }
            else
            {
                _comment = value;
            }
        }
    }
}

Siehe auch

Konzepte

Anpassen von Objekten (Entity Framework)