Question Explain DataTable copy

Citabria

Member
Joined
May 1, 2010
Messages
14
Programming Experience
1-3
Hi,
I am trying to understand copying of DataTables and processing changes.

I have created a DataTable dt1 (with not rows) in a Dataset ds1 and persisted it into an XML file.
And set Column 1 as a Primary Key and an Autoincrement Integer:
VB.NET:
            Dim key(0) As DataColumn
            key(0) = dt1.Columns("ID")
            dt1.PrimaryKey = key

            dt1.Columns("ID").AutoIncrement = True
If I read the XML into ds1
then create a new DataTable dt2:
VB.NET:
         Private dt2 as DataTable = new DataTable
(it has 0 rows)

then in a Form (Form1) copy dt1 into dt2:
......
VB.NET:
dt2 = ds1.Tables(dt1).Copy

then load a DataGridView (dgv1) control with dt2
VB.NET:
      dgv1.DataSource = dt2
Then I add a row using the DatagridView (dgv1)
Then I look at dt2
And find as expected that dt2 has 1 row (the row I added)
Then I look at the changes to dt2:
VB.NET:
       Dim dt1Chng As DataTable = dt2.GetChanges
       Dim dr As DataRow

       For Each dr In dt2Chng.Rows
            st = dr.RowState
            st = dr("ID").ToString
I find the RowState = 4
and ID = 0
again as expected

Now what I don't understand is if I clear dt1 and copy dt2 back into dt1
VB.NET:
        dt1.Clear()
        dt1 = dt2.Copy
        ds1.AcceptChanges()
dt2 still has 1 row
but dt1 has 0 rows

the copy appears to have failed but without errors.

Why is that?
does it have anything to do with the primary key or autoincrement?

Thanks for any light you can shed on this.

Doug
 
Last edited by a moderator:
It would have been better if you'd posted a full code sample. There is no overload of the Tables() property that accepts a DataTable object, only ints and strings (so your code as posted must have a compilation error)


Your problem is probably in the logic here:

VB.NET:
dt1.Clear()
dt1 = dt2.Copy
ds1.AcceptChanges()

On line 1, the dt1 variable probably refers to the datatable in the dataset (I can't be sure - you didnt post a full code sample and you do things in your code such as making a new object and then immediately overwriting it with another, which are confusing)

So you've got a dataset, with a tables collection, and it contains one datatable which you claim to have established another variable(not in your code - this is why we need full code samples), dt1, to point to also. ds.Tables(0) is pointing to a datatable, and dt1 is pointing to the same datatable

You cleared the datatable that both these vars point to in line 1

then on line 2 you made a whole, brand new copy of a datatable, and repointed your dt1 variable to the brand new object. Now dataset.Tables(0) points to the old thing you just cleared and dt1 points to the new thing you just copied, and youre testing the old thing (not in your code - this is why we need full code samples) - i.e. yure testing ds.Tables(0) and expecting it to contain the row from dt2, which it wont, because ds.Tables(0), dt1 and dt2 all point to different things now

-

Post a full code sample project highlighting the issue and I'll tell you where it went wacky.. That you clear dt1 (for example) before pointing the variable to a whole new object outlines to me that youre confused about what the Copy command does..

It doesnt copy the contents of dt2 into the existing dt1 (that would be dt2.CopyInto(dt1) ), it clones the entire datatable as a new object and returns it, and you store it in dt1 - the old object that was in dt1 is disposed of if there are no surviving refrences

it's like this:

Dim s as String = "My String"
s = myObject.ToString()

There was no sense in constructing the first string because the thing you did right after was throw it away and have the s variable point to the new string built and returned by the ToString() call
 
Hi,

Sorry I dont have the full code here, the objective is to build an entry form with a DGV to edit data but that would not directly edit the dataset. at the end of editing the user could choose to save the data or discard. If they save then the save process would do what ever checks and additional processing was required and then write it back to the original DataSet.

I didn't show
dt1=ds1.Tables(dt1)
sorry i had hoped that was intuitive, I showed:
dt2 = ds1.Tables(dt1).Copy

so assuming the code is something like:

Private dt2 as DataTable = new DataTable

dt1=ds1.Tables(dt1)
dt2 = dt1.Copy

dgv1.DataSource = dt2

Add row using the DataGridView (dgv1)

then save process would check fields etc

then

dt1.Clear() 'Clear out the original data
dt1 = dt2.Copy 'copy the cleaned up data back into the original dt
ds1.AcceptChanges()
ds1.WriteXML(...............)

you advise"You cleared the datatable that both these vars point to in line 1"

So you are saying that ds1.Tables("dt1") is now empty (cleared)
dt2 is as it is holding the new data
and dt1 is a new DataTable no longer pointing to ds1.Tables("dt1")

OK, so I can see that now. So how can I reflect the new changes back into
ds1.Tables("dt1")

And is there a more elegant way of attacking this type of structure?


Doug
 
Erm.. if the user enters a load of data, but then wants to cancel, why don't you just call datatable.RejectChanges? It will cause the added row to disappear

I've attached an example project, unfortunately in c# (but it's still readable, only 7 lines of code), but it has the EXE in there if you want to run it
Run it, you see existing data as if it has downloaded from a DB. Click the + to add another row. Edit the text boxes. (note the grid doesnt refresh; didn't tell it to, but you can cursor into the field to se ethe edit..)
Now click rejectChanges button.. Your changes disappear

<Attachment removed by moderator - No binary files in attachments please>
 
Last edited by a moderator:
Back
Top