Sunday, May 26, 2013

Comparing Original To Modified In A DataSet

We can easily determine which DataRows in a DataTable have changed. In fact, there are a couple of ways to do that, but it depends on what you intend to do when processing those changes. We can also determine which column of data has changed, but we'll tackle that topic second.

First thing I'll show are two ways to determine DataRow changes.

First option: you can loop through the every row, and determine it’s RowState, which will tell you if the DataRow has been modified or added:

foreach (DataTable dt in MyDataSet.Tables)
{
    foreach (DataRow row in dt.Rows)
    {
        if (row.RowState == DataRowState.Modified || row.RowState == DataRowState.Added)
        {
            // These are the actual rows that have some kind of changes
        }
    }
}

Second Option: If you’re not actually going to do anything with the actual rows, you just need to do some other kind of processing or validation or whatever, you can make use of the DataSet.GetChanges() method. This returns a DataSet containing only the changes (Modified or Added) from your original DataSet. Keep in mind that this is a new DataSet ( a new object) and has no “connection” to your original DataSet. Your code would then look like this:

DataSet dsChanged = MyDataSet.GetChanges();

foreach (DataTable dt in dsChanged.Tables)
{
    foreach (DataRow row in dt.Rows)
    {
        // these are copies of the rows that have some kind of changes
        // either Modified or Added (not the deleted rows)
    }
}

But what about columns that have changed?

Sometimes we want to know which columns have data that has changed. In this case, knowing that the DataRow has changed is not sufficient. That’s a different kettle of fish, but also quite easy to determine. We need to make use of something called a DataRowVersion. My example below will use the dsChanged DataSet from the above example, but the same logic can be applied to the actual MyDataSet object as well (keeping in mind that you need to test the RowState, as I show above).

foreach (DataTable dt in dsChanged.Tables)
{
    foreach (DataRow row in dt.Rows)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if (!row[i, DataRowVersion.Current].Equals(row[i, DataRowVersion.Original]))
            {
                // This particular Column has some kind of changes 
            }
        }
    }
}

And that’s it! Hope this helps someone!