Home All Groups Group Topic Archive Search About

DataSet - GetChanges() and Merge() Questions

Author
22 Jun 2006 3:36 PM
JimHus
I need to collect a "delta" between two Datasets: DS1 and DS2. DS2 was
created from DS1.

We cannot use/rely on RowState because of the operations involved in
generating DS2. Essentially all rows/columns are deleted and most are
re-added.

Can I use Merge between DS1/DS2 to generate a "Delta" Dataset? Something like:

DS1=DS2.Copy();
....
// Code that extensively modifies the DS2 Dataset
....
DS1.AcceptChanges(); // Reset RowState info - it is useless
DS2.AcceptChanges(); // Reset RowState info - it is useless
DS1.Merge(DS2, true);
sChanges = DS1.getChanges().GetXML();

I end up geting some XML - but it seems to bear little relation to the
changed area of the DataSet. Perhaps the RowState is killing me... is there a
way to get GetChanges() to work even if RowState is not valid?

It appears Merge() requires a Primary Key in order to detect row changes vs.
additions. Are there other limitations to using Merge?

Sorry for such a generic request. Worst case I will walk thru each table in
the Dataset determining changes/adds/etc... but I hate to do this if it's
already covered in the existing methods.

Thanks.

Jim

Author
22 Jun 2006 4:43 PM
Carl Prothman
Jim,
Why are you making a copy of DS1 and modifing DS2?   Why not just modify DS1?

Also, how are you obtaining DS1?  If you are using a Select statement, then the RowState should be Unchanged.  Or if you are adding rows to the DataTable, then you should call AcceptChanges() after the inserts. Then if you make changes (add, modify, delete), the RowState should change. You can use GetChanges() to geta a copy of the DataTable containing all changes made to it since it was last loaded or AcceptChanges() was called.  Is this not working for you?

Note if you use .NET framework 2.0, then you can set RowState by use the DataRow's SetModified() and SetAdded() methods.
http://msdn2.microsoft.com/en-us/system.data.datarow.setmodified.aspx
http://msdn2.microsoft.com/en-us/system.data.datarow.setadded.aspx

--

Thanks,
Carl Prothman
Microsoft ASP.NET MVP
http://www.CarlProthman.NET



Show quote
"JimHus" <Jim***@discussions.microsoft.com> wrote in message news:40AB1013-A312-487E-9F79-734CED4E7C21@microsoft.com...
>I need to collect a "delta" between two Datasets: DS1 and DS2. DS2 was
> created from DS1.
>
> We cannot use/rely on RowState because of the operations involved in
> generating DS2. Essentially all rows/columns are deleted and most are
> re-added.
>
> Can I use Merge between DS1/DS2 to generate a "Delta" Dataset? Something like:
>
> DS1=DS2.Copy();
> ...
> // Code that extensively modifies the DS2 Dataset
> ...
> DS1.AcceptChanges(); // Reset RowState info - it is useless
> DS2.AcceptChanges(); // Reset RowState info - it is useless
> DS1.Merge(DS2, true);
> sChanges = DS1.getChanges().GetXML();
>
> I end up geting some XML - but it seems to bear little relation to the
> changed area of the DataSet. Perhaps the RowState is killing me... is there a
> way to get GetChanges() to work even if RowState is not valid?
>
> It appears Merge() requires a Primary Key in order to detect row changes vs.
> additions. Are there other limitations to using Merge?
>
> Sorry for such a generic request. Worst case I will walk thru each table in
> the Dataset determining changes/adds/etc... but I hate to do this if it's
> already covered in the existing methods.
>
> Thanks.
>
> Jim
Author
22 Jun 2006 6:00 PM
JimHus
Carl,

I over-simplified in order to present as quickly as possible. A bad idea ;-(

Basically our dataset of tables are each 'dis-assembled' with most rows
becoming columns and vise-versa. The UI allows the users to add in new
'columns' or delete existing 'columns' in the UI. These columns actually
correspond to rows in the original Dataset.

But essentially once we have converted thru this row->columns, edits,
columns->rows routines -- all rows in the Dataset are flagged as Added - even
if there were no 'net' changes to them.

So the RowState has to be disregarded: The Dataset we get back will have the
exact same schema as the original (and most of the data) but is a completely
new set of tables.

> Jim,
> Why are you making a copy of DS1 and modifying DS2?   Why not just modify DS1?
>

Again - bad communication from trying to be terse...this code snippet should
be more clear.


dsOriginal=dsLive.Copy();
....
// Code that extensively modifies the dsLive() Dataset
....

// Flag initial state as clean
dsLive.AcceptChanges();
dsOriginal.AcceptChanges();

// Merge in the changes from dsLive:
//     this should not only give us the ds changes, but
//     the apropriate RowState for those changes also.
dsOriginal.Merge(dsLive, true);

// GetChanges() should present us with a 'delta' between the DataSets
sChanges = dsOriginal.getChanges().GetXML();

Steps
------
o  dsOriginal contains the DataSet prior to any changes.
o  dsLive is the final DataSet after modifications.
o  Reset the RowState
o  Merge should result in the differences being moved into
    dsOriginal and flagged with viable RowStates.
o  Use GetChanges() to list off the 'delta'


Jim

Show quote
"Carl Prothman" wrote:
> Also, how are you obtaining DS1?  If you are using a Select statement, then the RowState should be Unchanged.  Or if you are adding rows to the DataTable, then you should call AcceptChanges() after the inserts. Then if you make changes (add, modify, delete), the RowState should change. You can use GetChanges() to geta a copy of the DataTable containing all changes made to it since it was last loaded or AcceptChanges() was called.  Is this not working for you?
>
> Note if you use .NET framework 2.0, then you can set RowState by use the DataRow's SetModified() and SetAdded() methods.
> http://msdn2.microsoft.com/en-us/system.data.datarow.setmodified.aspx
> http://msdn2.microsoft.com/en-us/system.data.datarow.setadded.aspx
>
> --
>
> Thanks,
> Carl Prothman
> Microsoft ASP.NET MVP
> http://www.CarlProthman.NET
>
Author
23 Jun 2006 5:11 AM
Carl Prothman
"JimHus" <Jim***@discussions.microsoft.com> wrote
> Basically our dataset of tables are each 'dis-assembled' with most rows
> becoming columns and vise-versa. The UI allows the users to add in new
> 'columns' or delete existing 'columns' in the UI. These columns actually
> correspond to rows in the original Dataset.
>
>
> So the RowState has to be disregarded: The Dataset we get back will have the
> exact same schema as the original (and most of the data) but is a completely
> new set of tables.
>

Jim,
Keep in mind that when merging a new source DataSet into the target, any source rows with a DataRowState value of Unchanged, Modified, or Deleted are matched to target rows with the same primary key values. Source rows with a DataRowState value of Added are matched to new target rows with the same primary key values as the new source rows.
http://msdn2.microsoft.com/en-us/library/4swwh51k.aspx

Since you are not using the built-in RowState feature in DS2, you'll need to keep track of the changes yourself (e.g. add a custom RowState column and set it when you make a change). Then you'll need to write code to do the merge using your custom RowState column.  e.g. Apply the added, modified, and deleted rows from DS2 to DS1. After this DS1 should have the correct RowState, and hence you can use the SqlDataAdapter's Update method to apply the changes to the back-end database.

--

Thanks,
Carl Prothman
Microsoft ASP.NET MVP
http://www.CarlProthman.NET

AddThis Social Bookmark Button