Oftentimes we encounter problems when we perform update using LoadDataRow or rollback data using
RejectChanges after the Delete method. Why do the methods sometimes not do what we want?
Googling a solution for LoadDataRow, we may find that most people resolve the update performed by
LoadDataRow must call DataTable.AcceptChanges first. Does this solution work for you 100%?
There are still some unresolved posts left unanswered. They follow the solution to call
AcceptChanges but the problem still exists. Why?
Deleting a DataRow and then immediately performing RejectAccepts to rollback cause us to
receive System.Data.RowNotInTableException. What is it going on?
Is the DataRow marked as Deleted? Why can't I rollback?
The above problems are related to either the
RowState of a
DataRow or
if we set up the constraints on
DataTable correctly.
Assuming there is no constraint problem, the DataRow must be either Unchanged or Modified
when we perform an update using the LoadDataRow method on an existing DataRow.
The same principle applies to the RejectChanges after calling
the Delete method. Apparently, the operations requires an Original version existed for
the DataRow. When the RowState of DataRow is Unchanged or Modified, an Original version
of the DataRow has been created/existed. Thus, any operations after it won't cause a problem.
If you receive a System.Data.ConstraintException in regard to
System.Data.UniqueConstraint.CheckConstraint, please ensure the primary key set up properly.
Most likely, setting the Unique property of a DataColumn without primary key to true will
cause this problem to occur.
If you receive a System.Data.ConstraintException in regard to
System.Data.DataTable.EnableConstraints, please ensure an Original version existed for the
DataRow. It means the RowState of the DataRow is still in the state of Added and you need to commit
changes first by calling the AcceptChanges method to update the state to Unchanged.
Similarly, if you receive a System.Data.RowNotInTableException when you try to roll back
the DataRow after having called the Delete method, a AcceptChanges call is required before
the Delete method. After AcceptChanges, an Original version of the DataRow is created and
the RowState of the DataRow is set to Unchanged. From this state onwards, any modification
including the LoadDataRow method, or calling the Delete method and then the RejectChanges
method can be performed.
To sum up what the RowState means is described in the following table.
Detached | The DataRow is created but it hasn't been added to a DataTable yet.
Since it does not exist in a DataTable, no operations can be performed at the DataTable level. |
Added | The DataRow is added to a DataTable but the DataTable has not accepted changes yet.
At this stage, it requires AcceptChanges to create Original version for other update
operations including rollback.
|
Unchanged | The DataRow has not changed since the last AcceptChanges call.
At this stage, an Original version of the DataRow has already existed. Thus, any operations
can be performed without a problem. |
Modified | The DataRow has been modified since the last AcceptChanges call.
Like Unchanged, an Original version of the DataRow has already existed in this stage.
A DataRow with Modified row state can continously be modified but the RejectChanges will
only roll the data back to the last AcceptChanges call. Any modification made in between
is disgarded because the Original version of the DataRow is only pointing the copy when
the last AcceptChanges is called. |
Deleted | The DataRow was deleted by using the Delete method of the DataRow
only when the RowState of the DataRow is Unchanged or Modified.
|
I also attach some test results I conducted for reference.