Detecting and counting changes in a dataset

M

Matt Burland

I have a dataset which consists of a main table and a bunch of child tables.
I want, firstly, to be able to detect if a particular record has changed,
but is there an easy and quick way to tell if the children of a datarow in
the parent table have been updated without iterating through all the
relationships and checking each one?
Currently I have this:

public bool HasChanges

{

get

{

DataRowView drv = (DataRowView)database[index.Position];

bool changed = (drv.Row.RowState == DataRowState.Modified);

foreach (DataRelation rel in database.Data.Relations)

{

if (changed)

break;

if (rel.ParentTable == database.Data.Tables["tblMain"])

{

DataRow[] child = drv.Row.GetChildRows(rel);

foreach(DataRow r in child)

{

changed = changed | r.RowState == DataRowState.Modified;

if (changed)

break;

}

}

}

return changed;

}

}

Which even with the breaks, which will let the program get out early once
it's found one change, still seems like it's horribly inefficent, especially
since most of the time there really won't be any changes. I want to be able
to display on my form (which shows one record from the main table plus info
from the child table) if this record has changed since being loaded from the
database, so I need to do this everytime the user navigates to a new record
in the database. Any ideas?

My other, related, question is how can I count how many records have been
changed? I can use GetChanges on the parent table and to get changes there
and then use GetChanges on all the child tables too. But if I add them
together I'm likely to overcount some records (where both the parent and the
child have been changed). Is there an efficient way to deal with this? This
is less of an issue than the first case since I don't expect to need to get
that number very often.

Any insight here is most welcome!

Thanks
 
M

Miha Markic

Hi Matt,

Nope, you should iterate through rows.

You do the same for count changes (GetChanges is a bit ineficient for this
purpose).
 
M

Matt Burland

Thanks for the reply Miha. So I should iterate through all the rows and test
each one in turn to see if they've changed rather than use GetChanges if all
I want is the number of changed rows? I guess I could see why that would be
faster (no need to actually make copies of all the data).
 
M

Miha Markic

Matt Burland said:
Thanks for the reply Miha. So I should iterate through all the rows and test
each one in turn to see if they've changed rather than use GetChanges if all
I want is the number of changed rows? I guess I could see why that would be
faster (no need to actually make copies of all the data).

Exactly.
 
M

Matt Burland

That's an option, but I still need to check the rows in the child tables
even in rows in the parent table are unchanged and then reconcile the data
so that I don't over count.
What I'm doing at the moment is iterating through every row in the main
table and, if the row in the main table is unchanged, grabbing all it's
children and iterating through them. It's no good just getting the changed
rows in the main table because I'll miss some records that are unchanged,
but their children have changed.
I guess I could add another boolean field to the main table (in code, not in
the original database) and then whenever the child is changed it could
update the field in the main table and thereby force the record in the main
table to be changed. That way I could get all the info I need directly from
the main table without iterating through every record in all tables even
when a majority of them were never even displayed. I think I'll try
that......

William Ryan said:
You could also use a Dataview and filter by Rowstate. Then you could just
use count. Here's a good article..

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnhcvb03/html/vb03g9.asp
Matt Burland said:
I have a dataset which consists of a main table and a bunch of child tables.
I want, firstly, to be able to detect if a particular record has changed,
but is there an easy and quick way to tell if the children of a datarow in
the parent table have been updated without iterating through all the
relationships and checking each one?
Currently I have this:

public bool HasChanges

{

get

{

DataRowView drv = (DataRowView)database[index.Position];

bool changed = (drv.Row.RowState == DataRowState.Modified);

foreach (DataRelation rel in database.Data.Relations)

{

if (changed)

break;

if (rel.ParentTable == database.Data.Tables["tblMain"])

{

DataRow[] child = drv.Row.GetChildRows(rel);

foreach(DataRow r in child)

{

changed = changed | r.RowState == DataRowState.Modified;

if (changed)

break;

}

}

}

return changed;

}

}

Which even with the breaks, which will let the program get out early once
it's found one change, still seems like it's horribly inefficent, especially
since most of the time there really won't be any changes. I want to be able
to display on my form (which shows one record from the main table plus info
from the child table) if this record has changed since being loaded from the
database, so I need to do this everytime the user navigates to a new record
in the database. Any ideas?

My other, related, question is how can I count how many records have been
changed? I can use GetChanges on the parent table and to get changes there
and then use GetChanges on all the child tables too. But if I add them
together I'm likely to overcount some records (where both the parent and the
child have been changed). Is there an efficient way to deal with this? This
is less of an issue than the first case since I don't expect to need to get
that number very often.

Any insight here is most welcome!

Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top