Obtaining changes made in the current edit session


Summary
This topic shows how to discover the changes made to a class in the current edit session or current edit operation.


About obtaining changes made in the current edit session

It is possible to obtain the changes made in an edit session using the IWorkspaceEdit2.EditDataChanges property. The data changes object returned exposes the data changes in the current edit session or current edit operation. This topic shows how and when to use these objects to discover changes.
An edit session must be active to get the data changes from within the edit session. Similarly, to get changes at the edit operation scope, an edit operation must be active. Using a value from the esriEditDataChangesType enumeration to define the scope, the IWorkspaceEdit2.EditDataChanges property can be accessed for an IDataChangesEx return type. The IDataChangesEx.ModifiedClasses property can then be used to get an enumerator containing the names of the changed classes. See the following code example:
[C#]
public IEnumBSTR GetModifiedClasses(IWorkspace workspace)
{
    IWorkspaceEdit2 workspaceEdit2 = (IWorkspaceEdit2)workspace;
    IDataChangesEx dataChanges = workspaceEdit2.get_EditDataChanges
        (esriEditDataChangesType.esriEditDataChangesWithinSession);
    return dataChanges.ModifiedClasses;
}
[VB.NET]
Public Function GetModifiedClasses(ByVal workspace As IWorkspace) As IEnumBSTR
    
    Dim workspaceEdit2 As IWorkspaceEdit2 = CType(workspace, IWorkspaceEdit2)
    Dim dataChanges As IDataChangesEx = workspaceEdit2.EditDataChanges(esriEditDataChangesType.esriEditDataChangesWithinSession)
    
    Return dataChanges.ModifiedClasses
    
End Function
It is important to note that the data changes are only current when EditDataChanges is called. This means that any edits made after this call will not be reflected in calls to the members of the IDataChangesEx interface.

Inspecting a modified class

The IDataChangesEx.ChangedIDs property can be used to retrieve a set of ObjectIDs for each type of operation that might have modified a class (insertions, updates, and so on). The following code example shows how to retrieve a set of IDs containing all of the inserted and deleted objects:
[C#]
// For example, className = "customers."
public IFIDSet InsertedAndDeletedIDs(IDataChangesEx dataChangesEx, String className)
{
    // Get the IDs of inserted rows.
    IFIDSet insertFidSet = dataChangesEx.get_ChangedIDs(className,
        esriDifferenceType.esriDifferenceTypeInsert);

    // Get the IDs of deleted rows.
    IFIDSet deleteNoChangeFidSet = dataChangesEx.get_ChangedIDs(className,
        esriDifferenceType.esriDifferenceTypeDeleteNoChange);

    // Join the two ID sets and return the result.
    IFIDSetOperator fidSetOperator = (IFIDSetOperator)insertFidSet;
    return fidSetOperator.Union(deleteNoChangeFidSet);
}
[VB.NET]
' For example, className = "customers."

Public Function InsertedAndDeletedIDs(ByVal dataChangesEx As IDataChangesEx, ByVal className As String) As IFIDSet
    
    ' Get the IDs of inserted rows.
    Dim insertFidSet As IFIDSet = dataChangesEx.ChangedIDs(className, esriDifferenceType.esriDifferenceTypeInsert)
    
    ' Get the IDs of deleted rows.
    Dim deleteNoChangeFidSet As IFIDSet = dataChangesEx.ChangedIDs(className, esriDifferenceType.esriDifferenceTypeDeleteNoChange)
    
    ' Join the two ID sets and return the result.
    Dim fidSetOperator As IFIDSetOperator = CType(insertFidSet, IFIDSetOperator)
    
    Return fidSetOperator.Union(deleteNoChangeFidSet)
    
End Function

Using a difference cursor

Difference cursors provide a way to iterate through modified objects and obtain specific information about what changes have been made. The ExtractEx method is very powerful because the difference cursor it returns (using the IDifferenceCursorEx interface) provides references to two versions of the modified objects; one representing its state before the edit session (or operation) and one representing its current state. See the following code example:
[C#]
public void DisplayModifiedValues(IDataChangesEx dataChangesEx, String className)
{
    // Get a cursor over the updated rows.
    IDifferenceCursorEx differenceCursorEx = dataChangesEx.ExtractEx(className,
        esriDifferenceType.esriDifferenceTypeUpdateNoChange);

    // Prepare the output parameters.
    int featureID =  - 1;
    IRow sourceRow = null;
    IRow differenceRow = null;
    ILongArray fieldIndexes = null;

    // Iterate through the cursor.
    differenceCursorEx.Next(out featureID, out sourceRow, out differenceRow, out
        fieldIndexes);
    while (featureID !=  - 1)
    {
        Console.WriteLine("Changes for feature {0}:", featureID);

        // Go to each changed field and display the old and new values.
        for (int i = 0; i < fieldIndexes.Count; i++)
        {
            Console.WriteLine("Previous value: {0}", sourceRow.get_Value(i));
            Console.WriteLine("Current value: {0}", differenceRow.get_Value(i));
        }

        differenceCursorEx.Next(out featureID, out sourceRow, out differenceRow, out
            fieldIndexes);
    }
}
[VB.NET]
Public Sub DisplayModifiedValues(ByVal dataChangesEx As IDataChangesEx, ByVal className As String)
    
    ' Get a cursor over the updated rows.
    Dim differenceCursorEx As IDifferenceCursorEx = dataChangesEx.ExtractEx(className, esriDifferenceType.esriDifferenceTypeUpdateNoChange)
    
    ' Prepare the output parameters.
    Dim featureID As Integer = -1
    Dim sourceRow As IRow = Nothing
    Dim differenceRow As IRow = Nothing
    Dim fieldIndexes As ILongArray = Nothing
    
    ' Iterate through the cursor.
    differenceCursorEx.Next(featureID, sourceRow, differenceRow, fieldIndexes)
    Do While featureID <> -1
        Console.WriteLine("Changes for feature {0}:", featureID)
        
        ' Go to each changed field and display the old and new values.
        For i As Integer = 0 To fieldIndexes.Count - 1
            Console.WriteLine("Previous value: {0}", sourceRow.Value(i))
            Console.WriteLine("Current value: {0}", differenceRow.Value(i))
        Next i
        
        differenceCursorEx.Next(featureID, sourceRow, differenceRow, fieldIndexes)
        
    Loop
    
End Sub

Complete code examples

The following is the complete code example using these objects. The code outputs all changes that occurred in the defined scope.
[C#]
public void ShowChangesForScope(IWorkspace workspace, esriEditDataChangesType scope)
{
    IWorkspaceEdit2 workspaceEdit2 = (IWorkspaceEdit2)workspace;
    IDataChangesEx dataChangesEx = workspaceEdit2.get_EditDataChanges(scope);

    // Show the changes for each modified class in the workspace.
    IEnumBSTR modifiedClasses = dataChangesEx.ModifiedClasses;
    String modifiedClass = null;
    while ((modifiedClass = modifiedClasses.Next()) != null)
    {
        IDifferenceCursorEx differenceCursorEx = dataChangesEx.ExtractEx
            (modifiedClass, esriDifferenceType.esriDifferenceTypeUpdateNoChange);

        int featureOID =  - 1;
        IRow sourceRow = null;
        IRow differenceRow = null;
        ILongArray longArray = null;

        // Get the row values and featureOID.
        differenceCursorEx.Next(out featureOID, out sourceRow, out differenceRow,
            out longArray);
        Console.WriteLine("Updates for class {0}:", modifiedClass);
        while (featureOID !=  - 1)
        {
            Console.WriteLine("Feature OID: {0}", featureOID);

            // Display each changed field value.
            for (int i = 0; i < longArray.Count; i++)
            {
                Console.WriteLine("Was: {0} Is Now: {1}", differenceRow.get_Value
                    (longArray.get_Element(i)), sourceRow.get_Value
                    (longArray.get_Element(i)));
            }
            Console.WriteLine();
            differenceCursorEx.Next(out featureOID, out sourceRow, out differenceRow,
                out longArray);
        }

        // Get a FID set for all of the deleted features.
        IFIDSet2 deletedFIDSet = (IFIDSet2)dataChangesEx.get_ChangedIDs
            (modifiedClass, esriDifferenceType.esriDifferenceTypeDeleteNoChange);
        IEnumIDs deletedEnumIDs = deletedFIDSet.IDs;
        int nextDeletedID =  - 1;
        while ((nextDeletedID = deletedEnumIDs.Next()) !=  - 1)
        {
            Console.WriteLine("Deleted FID: {0}", nextDeletedID);
        }

        // Get a FID set for all of the inserted features.
        IFIDSet2 insertedFIDSet = (IFIDSet2)dataChangesEx.get_ChangedIDs
            (modifiedClass, esriDifferenceType.esriDifferenceTypeInsert);
        IEnumIDs insertedEnumIDs = insertedFIDSet.IDs;
        int nextInsertedID =  - 1;
        while ((nextInsertedID = insertedEnumIDs.Next()) !=  - 1)
        {
            Console.WriteLine("Inserted FID: {0}", nextInsertedID);
        }
    }
}
[VB.NET]
Public Sub ShowChangesForScope(ByVal workspace As IWorkspace, ByVal scope As esriEditDataChangesType)
    
    Dim workspaceEdit2 As IWorkspaceEdit2 = CType(workspace, IWorkspaceEdit2)
    Dim dataChangesEx As IDataChangesEx = workspaceEdit2.EditDataChanges(scope)
    
    ' Show the changes for each modified class in the workspace.
    Dim modifiedClasses As IEnumBSTR = dataChangesEx.ModifiedClasses
    Dim modifiedClass As String = Nothing
    Do While Not modifiedClass Is Nothing
        
        Dim differenceCursorEx As IDifferenceCursorEx = dataChangesEx.ExtractEx(modifiedClass, esriDifferenceType.esriDifferenceTypeUpdateNoChange)
        
        Dim featureOID As Integer = -1
        Dim sourceRow As IRow = Nothing
        Dim differenceRow As IRow = Nothing
        Dim longArray As ILongArray = Nothing
        
        ' Get the row values and featureOID.
        differenceCursorEx.Next(featureOID, sourceRow, differenceRow, longArray)
        Console.WriteLine("Updates for class {0}:", modifiedClass)
        
        Do While featureOID <> -1
            Console.WriteLine("Feature OID: {0}", featureOID)
            
            ' Display each changed field value.
            For i As Integer = 0 To longArray.Count - 1
                Console.WriteLine("Was: {0} Is Now: {1}", differenceRow.Value(longArray.Element(i)), sourceRow.Value(longArray.Element(i)))
            Next i
            
            Console.WriteLine()
            differenceCursorEx.Next(featureOID, sourceRow, differenceRow, longArray)
        Loop
        
        ' Get a FID set for all of the deleted features.
        Dim deletedFIDSet As IFIDSet2 = CType(dataChangesEx.ChangedIDs(modifiedClass, esriDifferenceType.esriDifferenceTypeDeleteNoChange), IFIDSet2)
        Dim deletedEnumIDs As IEnumIDs = deletedFIDSet.IDs
        Dim nextDeletedID As Integer = -1
        
        Do While nextDeletedID <> -1
            Console.WriteLine("Deleted FID: {0}", nextDeletedID)
            nextDeletedID = deletedEnumIDs.Next()
        Loop
        
        ' Get a FID set for all of the inserted features.
        Dim insertedFIDSet As IFIDSet2 = CType(dataChangesEx.ChangedIDs(modifiedClass, esriDifferenceType.esriDifferenceTypeInsert), IFIDSet2)
        Dim insertedEnumIDs As IEnumIDs = insertedFIDSet.IDs
        Dim nextInsertedID As Integer = -1
        
        Do While nextInsertedID <> -1
            Console.WriteLine("Inserted FID: {0}", nextInsertedID)
            nextInsertedID = insertedEnumIDs.Next()
        Loop
        
        modifiedClass = modifiedClasses.Next()
        
    Loop
    
End Sub


See Also:

Finding differences between versions




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS for Desktop Basic ArcGIS for Desktop Basic
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine