What is the purpose of AcceptChanges?

J

Jerry H.

I know that sounds like a lame and newbie kind of question, because I
understand what the effect is - but I'd really like to know what
Microsoft's thinking behind this method is about.

For example, I can pull ten rows from a datasource into a dataset,
modify the contents of a few rows and then send the changes back to
the original datasource using the Update method of an adapter. But if
I call AcceptChanges manually prior to the Update method, then there
are no changes available in the dataset for the adapter to send back.
What is the reason for this behavior? Under what circumstances would
I want to call AcceptChanges manually anyway, if I know that I will
send changes back to the original database later on?

As I understand it, a Datatable can have 3 versions of a field:
Original, Current and Pending. I believe AcceptChanges "pushes" the
Pending values into the Current values, whereas the Original values
reflect the last known state of data from the datasource.

It seems to me, that if I have data that has been updated on the
dataset, why wouldn't the Update method of the adapter see that
automatically and send back the changes?

I know I am missing something simple that should help fill in my gaps
of ADO.NET, please help a coda out!
 
W

William \(Bill\) Vaughn

As I discuss in the book, AcceptChanges is rarely used--unless you've
handling the events fired by the Update method. In other words it's only
used after your event handlers have dealt with the rows being changed. Yes,
when using the Update method in typical fashion it's not required.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
 
J

Jim Rand

Unless you have logic like this to handle multiple related tables in a
dataset where you do the deleted first up the parent chain, the added next
down the chain, followed by the modified down the chain:

System.Data.DataSet dsDeleted =
ds.GetChanges(System.Data.DataRowState.Deleted);
System.Data.DataSet dsAdded = ds.GetChanges(System.Data.DataRowState.Added);
System.Data.DataSet dsModified =
ds.GetChanges(System.Data.DataRowState.Modified);

UpdateOperation(dsDeleted, adapterList, System.Data.DataRowState.Deleted);
UpdateOperation(dsAdded, adapterList, System.Data.DataRowState.Added);
UpdateOperation(dsModified, adapterList, System.Data.DataRowState.Modified);

if (dsDeleted != null) ds.Merge(dsDeleted, false);
if (dsAdded != null) ds.Merge(dsAdded, false);
if (dsModified != null) ds.Merge(dsModified, false);

ds.AcceptChanges();

In which, you will call AcceptChanges
 
B

Bart Mermuys

Hi,

Jerry H. said:
I know that sounds like a lame and newbie kind of question, because I
understand what the effect is - but I'd really like to know what
Microsoft's thinking behind this method is about.

For example, I can pull ten rows from a datasource into a dataset,
modify the contents of a few rows and then send the changes back to
the original datasource using the Update method of an adapter. But if
I call AcceptChanges manually prior to the Update method, then there
are no changes available in the dataset for the adapter to send back.
What is the reason for this behavior? Under what circumstances would
I want to call AcceptChanges manually anyway, if I know that I will
send changes back to the original database later on?

As I understand it, a Datatable can have 3 versions of a field:
Original, Current and Pending.

- A DataRow can have different RowState's and each RowState indicates what
values a DataRow has:
DataRowState.Unmodified Original and Current (O==C)
DataRowState.Modified Original and Current
DataRowState.Deleted none or Original
DataRowState.Added Current
DataRowState.Detached Proposed

- The following RowState's can also have a Proposed value during edit (after
BeginEdit is called and at least one field has been set):
DataRowState.Unmodified,
DataRowState.Modified &
DataRowState.Added

- Then when you call EndEdit, Proposed values get into Current values and
Proposed values are removed, also the RowState will change for:
DataRowState.Unmodified => DataRowState.Modified

- AcceptChanges works differently depending on the RowState:
RowState.Modified =>Current into Original =>RowState.Unmodified
RowState.Added =>Current into Original =>RowState.Unmodified
RowState.Deleted =>row removed from DataTable

If you would call AcceptChanges on the DataTable then it's applied to all
DataRows, after that all (leftover) DataRows will have a RowState.Unmodified
and therefore the DataAdapter won't do anything. And also the Original
values aren't the ones fetched from the DB anymore, so the DataAdapter
couldn't do optimistic concurrency control using the Original values.
I believe AcceptChanges "pushes" the
Pending values into the Current values, whereas the Original values
reflect the last known state of data from the datasource.

No, Proposed (Pending) values are only used when BeginEdit was called and go
into Current values when EndEdit is called. Current values go into Original
when AcceptChanges is called.

Here is some _simplified code_ for DataAdapter.Fill and Update to illustrate
the different RowState's and AcceptChanges:

- DataAdapter.Fill():
foreach (fetched record)
{
row = table.NewRow(); // Detached
row[ .. ] = ...;
table.Rows.Add(row); // Added
row.AcceptChanges() // Unmodified
}

- Change value:
tables.Rows[0].BeginEdit();
tables.Rows[0]["col1"] = "..." // still Unmodified but has Proposed value
now
tables.Rows[0].EndEdit(); // Modified

- DataAdapter.Update():
foreach (modified row)
{
run update command using row values
row.AcceptChanges(); // Unmodified
}

HTH,
Greetings
 
F

Frans Bouma [C# MVP]

William said:
As I discuss in the book, AcceptChanges is rarely used--unless you've
handling the events fired by the Update method. In other words it's
only used after your event handlers have dealt with the rows being
changed. Yes, when using the Update method in typical fashion it's
not required.

AcceptChanges is used by every grid on the planet, indirectly, via
IEditableObject on the row of a dataview. AcceptChanges is called
indirectly via IEditableObject.EndEdit() when the row is finalized.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
F

Frans Bouma [C# MVP]

OHH I'm an Idiot...

I didn't re-read the acceptchanges docs. My bad, ignore the text below,
I was wrong.

FB
 
C

Cor Ligthert [MVP]

Jerry,

There are many purposes of the AcceptChanges, however probably the most
important is:
As soon as you start with updating Datasest with related tables, than you
can not use the standard update.

You have to give to the server the rows in the way based on the rowstate.
You make for that a copy of your DataSet with only those rows with a certain
rowstate as the others have described.

That has to be done in a special sequence. First of all you delete all
childrows, than delete all parentrows, than create all parentrows, than
create all childrows. Where you do the changes is not so important. (I write
this without checking)

After you have done all those updates you have to do a Acceptchanges from
your dataset to set it to , because the inbuild feature in the DataAdapter
is than setting the rowstates of the copies.

Cor
 
C

Cor Ligthert [MVP]

Frans,

What a pity you saw that. I would have written a nice message for you.

:)

Cor
 
R

Rad [Visual C# MVP]

I know that sounds like a lame and newbie kind of question, because I
understand what the effect is - but I'd really like to know what
Microsoft's thinking behind this method is about.

For example, I can pull ten rows from a datasource into a dataset,
modify the contents of a few rows and then send the changes back to
the original datasource using the Update method of an adapter. But if
I call AcceptChanges manually prior to the Update method, then there
are no changes available in the dataset for the adapter to send back.
What is the reason for this behavior? Under what circumstances would
I want to call AcceptChanges manually anyway, if I know that I will
send changes back to the original database later on?

As I understand it, a Datatable can have 3 versions of a field:
Original, Current and Pending. I believe AcceptChanges "pushes" the
Pending values into the Current values, whereas the Original values
reflect the last known state of data from the datasource.

It seems to me, that if I have data that has been updated on the
dataset, why wouldn't the Update method of the adapter see that
automatically and send back the changes?

I know I am missing something simple that should help fill in my gaps
of ADO.NET, please help a coda out!

Generally you wouldn't have to call it yourself. However there may be some
exceptions. For instance the Sybase ASA 10 provider for some reason seems
to require you to explicitly call AcceptChanges even after calling
update... I'm inclined to think its a bug
 
J

Jerry H.

Thanks for the replies everyone, the info here is very useful and
helped to shed more light on this subject for me!
 

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