This documentation is archived and is not being maintained.

DataSet.GetChanges Method ()

.NET Framework 1.1

Gets a copy of the DataSet that contains all changes made to it since it was loaded or AcceptChanges was last called.

[Visual Basic]
Overloads Public Function GetChanges() As DataSet
[C#]
public DataSet GetChanges();
[C++]
public: DataSet* GetChanges();
[JScript]
public function GetChanges() : DataSet;

Return Value

A copy of the changes from this DataSet that can have actions performed on it and subsequently be merged back in using Merge, or a null reference (Nothing in Visual Basic) if none are found.

Remarks

Gets a copy of the DataSet that contains all changes made to it since it was loaded or AcceptChanges was last called. This copy is particularly designed so that it can be merged back in to this original DataSet. Relationship constraints may cause Unchanged parent rows to be included. If no rows of these rowStates are found, this method returns a null reference (Nothing in Visual Basic).

Example

[Visual Basic, C#, C++] The following example creates a simple DataSet with one table, two columns, and ten rows. Two values are changed, and one row is added. A subset of the changed data is created using the GetChanges method. After reconciling errors, a new column is added to the subset, changing the schema. When the Merge method is called with the missingSchemaAction set to MissingSchemaAction.Add. the new column is added to the original DataSet object's schema.

[Visual Basic] 
Private Sub DemonstrateMerge()
    ' Create a DataSet with one table, two columns, and three rows.
    Dim ds As New DataSet("myDataSet")
    Dim t As New DataTable("Items")
    Dim c1 As New DataColumn("id", Type.GetType("System.Int32"), "")
    c1.AutoIncrement = True
    Dim c2 As New DataColumn("Item", Type.GetType("System.Int32"), "")
    ' DataColumn array to set primary key.
    Dim keyCol(1) As DataColumn
    Dim r As DataRow
    ' Create variable for temporary DataSet. 
    Dim xSet As DataSet
    ' Add RowChanged event handler for the table.
    AddHandler t.RowChanged, AddressOf Row_Changed
    ds.Tables.Add(t)
    t.Columns.Add(c1)
    t.Columns.Add(c2)
    ' Set primary key column.
    keyCol(0) = c1
    t.PrimaryKey = keyCol
    ' Add ten rows.
    Dim i As Integer
    For i = 0 To 9
        r = t.NewRow()
        r("Item") = i
        t.Rows.Add(r)
    Next i
    ' Accept changes.
    ds.AcceptChanges()
    PrintValues(ds, "Original values")
    ' Change row values.
    t.Rows(0)("Item") = 50
    t.Rows(1)("Item") = 111
    ' Add one row.
    r = t.NewRow()
    r("Item") = 74
    t.Rows.Add(r)
    ' Insert code for error checking. Here we set one row in error.
    t.Rows(1).RowError = "over 100"
    PrintValues(ds, "Modified and New Values")
    ' If the table has changes or errors, create a subset DataSet.
    If ds.HasChanges(DataRowState.Modified Or DataRowState.Added) _
       And ds.HasErrors Then
        ' Use GetChanges to extract subset.
        xSet = ds.GetChanges(DataRowState.Modified Or DataRowState.Added)
        PrintValues(xSet, "Subset values")
        ' Insert code to reconcile errors. In this case, we'll reject changes.
        Dim xTable As DataTable
        For Each xTable In  xSet.Tables
            If xTable.HasErrors Then
                Dim xRow As DataRow
                For Each xRow In  xTable.Rows
                    'Console.WriteLine(xRow["Item"]);
                    If CInt(xRow("Item", DataRowVersion.Current)) > 100 Then
                        xRow.RejectChanges()
                        xRow.ClearErrors()
                    End If
                Next xRow
            End If
        Next xTable
        ' Add a column to the xSet.
        xSet.Tables("Items").Columns.Add(New DataColumn("newColumn"))
        PrintValues(xSet, "Reconciled subset values")
        ' Merge changes back to first DataSet.
        ds.Merge(xSet, False, System.Data.MissingSchemaAction.Add)
    End If
    PrintValues(ds, "Merged Values")
End Sub
       
Private Sub Row_Changed(sender As Object, e As DataRowChangeEventArgs)
    Console.WriteLine("Row Changed " + e.Action.ToString() _
       + ControlChars.Tab + e.Row.ItemArray(0).ToString())
End Sub
   
Private Sub PrintValues(ds As DataSet, label As String)
    Console.WriteLine(label + ControlChars.Cr)
    Dim t As DataTable
    For Each t In  ds.Tables
        Console.WriteLine("TableName: " + t.TableName)
        Dim r As DataRow
        For Each r In  t.Rows
            Dim c As DataColumn
            For Each c In  t.Columns
                Console.Write(ControlChars.Tab + " " + r(c).ToString())
            Next c
            Console.WriteLine()
        Next r
    Next t
End Sub

[C#] 
private void DemonstrateMerge(){
   // Create a DataSet with one table, two columns, and three rows.
   DataSet ds = new DataSet("myDataSet");
   DataTable t = new DataTable("Items");
   DataColumn c1 = new DataColumn("id", Type.GetType("System.Int32"),"");
   c1.AutoIncrement=true;
   DataColumn c2 = new DataColumn("Item", Type.GetType("System.Int32"),"");
   // DataColumn array to set primary key.
   DataColumn[] keyCol= new DataColumn[1];
   DataRow r;
   // Create variable for temporary DataSet. 
   DataSet xSet;
   // Add RowChanged event handler for the table.
   t.RowChanged+=new DataRowChangeEventHandler(Row_Changed);
   ds.Tables.Add(t);
   t.Columns.Add(c1);
   t.Columns.Add(c2);
   // Set primary key column.
   keyCol[0]= c1;
   t.PrimaryKey=keyCol;
   // Add ten rows.
   for(int i = 0; i <10;i++){
      r=t.NewRow();
      r["Item"]= i;
      t.Rows.Add(r);
   }
   // Accept changes.
   ds.AcceptChanges();
   PrintValues(ds, "Original values");
   // Change row values.
   t.Rows[0]["Item"]= 50;
   t.Rows[1]["Item"]= 111;
   // Add one row.
   r=t.NewRow();
   r["Item"]=74;
   t.Rows.Add(r);
   // Insert code for error checking. Here we set one row in error.
   t.Rows[1].RowError= "over 100";
   PrintValues(ds, "Modified and New Values");
   // If the table has changes or errors, create a subset DataSet.
   if(ds.HasChanges(DataRowState.Modified | DataRowState.Added)& ds.HasErrors){
      // Use GetChanges to extract subset.
      xSet = ds.GetChanges(DataRowState.Modified|DataRowState.Added);
      PrintValues(xSet, "Subset values");
      // Insert code to reconcile errors. In this case, we'll reject changes.
      foreach(DataTable xTable in xSet.Tables){
         if (xTable.HasErrors){
            foreach(DataRow xRow in xTable.Rows){
               //Console.WriteLine(xRow["Item"]);
                  if((int)xRow["Item",DataRowVersion.Current ]> 100){
                  xRow.RejectChanges();
                  xRow.ClearErrors();
               }
            }
         }
      }
      // Add a column to the xSet.
      xSet.Tables["Items"].Columns.Add(new DataColumn("newColumn"));
      PrintValues(xSet, "Reconciled subset values");
      // Merge changes back to first DataSet.
      ds.Merge(xSet,false,System.Data.MissingSchemaAction.Add);
   }
   PrintValues(ds, "Merged Values");
}

private void Row_Changed(object sender, DataRowChangeEventArgs e){
   Console.WriteLine("Row Changed " + e.Action.ToString() + "\t" + e.Row.ItemArray[0]);
}

private void PrintValues(DataSet ds, string label){
   Console.WriteLine(label + "\n");
   foreach(DataTable t in ds.Tables){
      Console.WriteLine("TableName: " + t.TableName);
      foreach(DataRow r in t.Rows){
         foreach(DataColumn c in t.Columns){
            Console.Write("\t " + r[c] );
         }
         Console.WriteLine();
      }
   }
}

[C++] 
private:
 void DemonstrateMerge(){
    // Create a DataSet with one table, two columns, and three rows.
    DataSet* ds = new DataSet(S"myDataSet");
    DataTable* t = new DataTable(S"Items");
    DataColumn* c1 = new DataColumn(S"id", Type::GetType(S"System.Int32"),S"");
    c1->AutoIncrement=true;
    DataColumn* c2 = new DataColumn(S"Item", Type::GetType(S"System.Int32"),S"");
    // DataColumn array to set primary key.
    DataColumn* keyCol[]= new DataColumn*[1];
    DataRow* r;
    // Create variable for temporary DataSet. 
    DataSet* xSet;
    // Add RowChanged event handler for the table.
    t->RowChanged+=new DataRowChangeEventHandler(this, &Form1::Row_Changed);
    ds->Tables->Add(t);
    t->Columns->Add(c1);
    t->Columns->Add(c2);
    // Set primary key column.
    keyCol[0]= c1;
    t->PrimaryKey=keyCol;
    // Add ten rows.
    for(int i = 0; i <10;i++){
       r=t->NewRow();
       r->Item[S"Item"]= __box(i);
       t->Rows->Add(r);
    }
    // Accept changes.
    ds->AcceptChanges();
    PrintValues(ds, S"Original values");
    // Change row values.
    t->Rows->Item[0]->Item[S"Item"]= __box(50);
    t->Rows->Item[1]->Item[S"Item"]= __box(111);
    // Add one row.
    r=t->NewRow();
    r->Item[S"Item"]=__box(74);
    t->Rows->Add(r);
    // Insert code for error checking. Here we set one row in error.
    t->Rows->Item[1]->RowError= S"over 100";
    PrintValues(ds, S"Modified and New Values");
    // If the table has changes or errors, create a subset DataSet.
    if(ds->HasChanges(static_cast<DataRowState>(DataRowState::Modified | DataRowState::Added))& ds->HasErrors){
       // Use GetChanges to extract subset.
       xSet = ds->GetChanges(static_cast<DataRowState>(DataRowState::Modified|DataRowState::Added));
       PrintValues(xSet, S"Subset values");
       // Insert code to reconcile errors. In this case, we'll reject changes.
       System::Collections::IEnumerator* myEnum = xSet->Tables->GetEnumerator();
       while (myEnum->MoveNext())
       {
          DataTable* xTable = __try_cast<DataTable*>(myEnum->Current);
          if (xTable->HasErrors){
             System::Collections::IEnumerator* myEnum1 = xTable->Rows->GetEnumerator();
             while (myEnum1->MoveNext())
             {
               DataRow* xRow = __try_cast<DataRow*>(myEnum1->Current);
                //Console.WriteLine(xRow["Item"]);
                   if(*dynamic_cast<Int32*>(xRow->get_Item(S"Item",DataRowVersion::Current)) > 100){
                   xRow->RejectChanges();
                   xRow->ClearErrors();
                }
             }
          }
       }
       // Add a column to the xSet.
       xSet->Tables->Item[S"Items"]->Columns->Add(new DataColumn(S"newColumn"));
       PrintValues(xSet, S"Reconciled subset values");
       // Merge changes back to first DataSet.
       ds->Merge(xSet,false,System::Data::MissingSchemaAction::Add);
    }
    PrintValues(ds, S"Merged Values");
 }
 
 void Row_Changed(Object* /*sender*/, DataRowChangeEventArgs* e){
    Console::WriteLine(S"Row Changed {0}\t{1}", __box(e->Action), e->Row->ItemArray[0]);
 }
 
 void PrintValues(DataSet* ds, String* label){
    Console::WriteLine(S"{0}\n", label);
    System::Collections::IEnumerator* myEnum2 = ds->Tables->GetEnumerator();
    while (myEnum2->MoveNext())
    {
       DataTable* t = __try_cast<DataTable*>(myEnum2->Current);
       Console::WriteLine(S"TableName: {0}", t->TableName);
       System::Collections::IEnumerator* myEnum3 = t->Rows->GetEnumerator();
       while (myEnum3->MoveNext())
       {
          DataRow* r = __try_cast<DataRow*>(myEnum3->Current);
          System::Collections::IEnumerator* myEnum4 = t->Columns->GetEnumerator();
          while (myEnum4->MoveNext())
          {
             DataColumn* c = __try_cast<DataColumn*>(myEnum4->Current);
             Console::Write(S"\t {0}", r->Item[c] );
          }
          Console::WriteLine();
       }
    }
 }

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family

See Also

DataSet Class | DataSet Members | System.Data Namespace | DataSet.GetChanges Overload List | HasChanges

Show: