Adding deleted rows back to a DataTable

F

Fardreamer

I'm trying to add rows marked as deleted back into their parent
DataRowCollection by using DataRowCollection.Add. The behavior I was
expecting was having the DataRowState switch back to it's last value
before the delete, i.e. Unchanged->Deleted->Unchanged,
Modified->Deleted->Modified, etc. Instead I get an ArgumentException
with the message "This row already belongs to this table." Obviously
the row does belong to the table, however it is not currently part of
it's row collection.

How would I go about implementing this? I know I can use RejectChanges
but that will revert the state back to the last Original, which will
undo any field changes as well. All I want to do is undo the last
Delete action. I was considering adding a duplicate new row and loading
the deleted row's values into it, but that might result in constraint
violations when running the related stored procedures against the data
source.

Thanks in advance.
 
C

Cor Ligthert [MVP]

Fardreamer,

Delete means that it will be deleted after an update or an acceptchanges.

datatable.Rows.RemoveAt .... or the remove(dr) means that it will be
removed.

(it it is a new added row than delete is function the same as remove)

I hope this helps,

Cor
 
M

Marina

You would have to Remove the row, and then add it. Calling Delete on it,
means it is marked for deletion - this is not the same as being actually
removed from the table.
 
F

Fardreamer

Thanks for the replies. If I use Remove or Remove at, the RowState will
become Detached abd the data will be inaccessible. Furthermore,
DataAdapter.Update won't use the appropriate command because it will
see Added instead of the desired value, which should be
Modified/Unchanged (unless it was actually added before the delete).
I'm writing an abstraction layer that is supposed to expose a table as
a collection of business objects and so I want the user to be able to
use all the standard collection features, such as Add, Remove, Insert,
etc.

Thanks again.
 
W

W.G. Ryan - MVP

A deleted rows Does belong to the table. If you have 20 rows, call delete
on all 20 and check Rows.count, you still have 20 rows. You may be able to
use the RowVersion (Current, Default, Original and Proposed) to get the data
you want.

Would calling AcceptChanges on the row before the delete work for you?
Another approach would be to use GetChanges before Calling Delete to get the
row with the last known good state. Now you have the row exactly as you
want it. If you want to get back, you can use it for your updates to the
db, or you can call AcceptChanges on the deleted row, and add the one
retrieved from GetChanges. Would either of these work for you?
 
C

Cor Ligthert [MVP]

Fardreamer,
Thanks for the replies. If I use Remove or Remove at, the RowState will
become Detached abd the data will be inaccessible.

Exact see this sample.
\\\
Dim dt As New DataTable
dt.Rows.Add(dt.NewRow)
dt.Rows.Add(dt.NewRow)
Dim dr As DataRow = dt.Rows(1)
dt.Rows.Remove(dr)
dt.Rows.InsertAt(dr, 0)
MessageBox.Show(dt.Rows.Count.ToString)
///

You are not able to add that detached row to a cloned table. It keeps a
reference to the original. for that you have to use the rowimport.

I hope this helps,

Cor
 
F

Fardreamer

Ryan,
I ended up using an approach similar to the second you suggest.
Basically I have a collection that encapsulates a DataTable and
indiviual objects that encapsulate a DataRow. The object exposes
properties that map to columns in the row. Calling
CollectionBase.Remove on an object causes Delete() to be called
internally on the row. So what I did is, whenever the state of the row
is Deleted or Detached and the object's properties are manipulated, I
store the values in a temporary hashtable. When the object is added to
the collection, I either RejectChanges if the state is Deleted or add
it if the state is Detached, and then I restore the values from the
hashtable. A little complicated but it works.

Cor, I'm not sure how in your example the row is being added to a
cloned table... you are just adding it back into the same table, am I
wrong?

Thanks for thet suggestions, much appreciated.
 
C

Cor Ligthert [MVP]

I'm not sure how in your example the row is being added to a
cloned table... you are just adding it back into the same table, am I
wrong?

I thought that this was your question.

So you are right. The cloned table I have told as extra because the
behaviour could have been that because it is removed it can be added
somewhere else.

A detached datarow keeps its reference to the datatable (probably because
otherwise it becomes completely without structure because in that are the
datacolumns described)

You can import a detached datarow to a cloned datatable. However becomes
than complete unreachable because it keeps its rowstate.

http://msdn.microsoft.com/library/d...lrfsystemdatadatatableclassimportrowtopic.asp

If you want to import a datarow from an other datatable, than import that
row in the cloned table and remove it after that from the original.

However that was not your question in my opinion, so the simple remove as
Marina an I wrote is probably your solution.

I hope this helps,

Cor
 
F

Fardreamer

Cor, that's not exactly what I'm looking for but that might come in
handy. In any case, as I stated in my previous post I solved the
problem using another method.

Thanks again for all the help.
 

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