Found Serious Bug!

T

Trey

If you have a datatable connected to a dataview.
And
In that dataview you have a "Sort" property set to a value;
And
You try to modify the "Sort" column in row in such a fashion that it gets
moved in the DataView
IT CAN
Corrupt your database.

A quick fix is to set the "Sort" property of the dataview to "" make your
changes and then set it back to it's original value.

Trey
 
V

Val Mazur

Hi,

Could you be more specific in this case? Could you post the code to
reproduce the bug?
 
S

Scott M.

I seriously doubt that since datatables and dataviews are copies of the data
from the database and in no way communicate directly to the database.

The only ADO.NET classes that do any direct communication with the actual
database are the DataAdapter and DataReader classes.
 
W

William Ryan eMVP

Trey:

The DataView doesn't give a hoot about the DB once you've created it. For
all it knows, the database who's data has populated it may not exist any
more. If anything is causing a corruption..it's got to be either your
update logic, some other code in the program or a corrupt database file.

I've seen this 'reported' before when people had stuff bound to a datagrid
and were using position in the grid as though it matched the underlying
datatable. That may or may not be the case based on sorting, but Something
has to send the update back to a database in order for anything to be
changed, and DataView's simply don't have that functionality. They
physically can't change a database so it's got to be your update logic..
HTH,

Bill
 
T

Trey

Of course I meant that it corrupted the data table and when I did a
DataAdapter.Update it correcupted the Database!

I have a database with this data in it for one of the tables

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- --------
--
1 Trey Weaver Trey say1.wav 1
2 Susan Weaver Susan say3.wav 2
3 Sam Smith Sammy say21.wav 3
4 Bill Smith Billy say4.wav
4

After doing these commands.

dr1.BeginEdit()
dr1[SortOrder} = 3;
dr1.EndEdit();
dr2.BeginEdit()
dr2[SortOrder} = 2;
dr2.EndEdit();
SaveData(); // updates the data adapter and table

The data now looks like this.

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- --------
--
1 Sam Smith Sammy say21.wav 2
// this is a duplicate
2 Susan Weaver Susan say3.wav 3
3 Sam Smith Sammy say21.wav 2
4 Bill Smith Billy say4.wav
4

I can set a breakpoint before and after this code check the database using
access. So I am confident that it is this code that causes the problem.

Notice that I never changed the FirstName field but yet it got changed in
the DataTable.

And Yes! I do have the datagrid connected to the dataview.
 
T

Trey

I should of said after I use the DataAdapter to write the data back to the
database it is corrupt. It is really the datatable that is getting corrupt.

Miha Markic said:
Huh?
How could it corrupt the database?

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Trey said:
If you have a datatable connected to a dataview.
And
In that dataview you have a "Sort" property set to a value;
And
You try to modify the "Sort" column in row in such a fashion that it gets
moved in the DataView
IT CAN
Corrupt your database.

A quick fix is to set the "Sort" property of the dataview to "" make your
changes and then set it back to it's original value.

Trey
 
M

Miha Markic [MVP C#]

Hi Trey,

I read your answer to william and I wonder how is your dataadapter
configured, specially UpdateCommand.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Trey said:
I should of said after I use the DataAdapter to write the data back to the
database it is corrupt. It is really the datatable that is getting corrupt.

Miha Markic said:
Huh?
How could it corrupt the database?

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Trey said:
If you have a datatable connected to a dataview.
And
In that dataview you have a "Sort" property set to a value;
And
You try to modify the "Sort" column in row in such a fashion that it gets
moved in the DataView
IT CAN
Corrupt your database.

A quick fix is to set the "Sort" property of the dataview to "" make your
changes and then set it back to it's original value.

Trey
 
T

Trey

Here you go.

//
// daTelephone
//
this.daTelephone.DeleteCommand =
this.oleDbDeleteCommand1;
this.daTelephone.InsertCommand =
this.oleDbInsertCommand1;
this.daTelephone.SelectCommand =
this.oleDbSelectCommand1;
this.daTelephone.TableMappings.AddRange(new
System.Data.Common.DataTableMapping[] {

new System.Data.Common.DataTableMapping("Table", "Telephone", new
System.Data.Common.DataColumnMapping[] {

new System.Data.Common.DataColumnMapping("FirstName", "FirstName"),

new System.Data.Common.DataColumnMapping("LastName", "LastName"),


new System.Data.Common.DataColumnMapping("PhoneNumber", "PhoneNumber"),

new System.Data.Common.DataColumnMapping("Say", "Say"),

new System.Data.Common.DataColumnMapping("SayFileName", "SayFileName"),

new System.Data.Common.DataColumnMapping("SortOrder", "SortOrder"),

new System.Data.Common.DataColumnMapping("theIndex", "theIndex")})});
this.daTelephone.UpdateCommand =
this.oleDbUpdateCommand1;
//
// oleDbDeleteCommand1
//
this.oleDbDeleteCommand1.CommandText = "DELETE FROM
Telephone WHERE (theIndex = ?)";
this.oleDbDeleteCommand1.Connection = this.cn;
this.oleDbDeleteCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Original_theIndex",
System.Data.OleDb.OleDbType.Integer, 0,
System.Data.ParameterDirection.Input, false, ((System.Byte)(0)),
((System.Byte)(0)), "theIndex", System.Data.DataRowVersion.Original, null));
//
// oleDbInsertCommand1
//
this.oleDbInsertCommand1.CommandText = "INSERT INTO
Telephone(FirstName, LastName, PhoneNumber, Say, SayFileName, SortOrd" +
"er) VALUES (?, ?, ?, ?, ?, ?)";
this.oleDbInsertCommand1.Connection = this.cn;
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("FirstName",
System.Data.OleDb.OleDbType.VarWChar, 50, "FirstName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("LastName",
System.Data.OleDb.OleDbType.VarWChar, 50, "LastName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("PhoneNumber",
System.Data.OleDb.OleDbType.VarWChar, 50, "PhoneNumber"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Say",
System.Data.OleDb.OleDbType.VarWChar, 50, "Say"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SayFileName",
System.Data.OleDb.OleDbType.VarWChar, 50, "SayFileName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SortOrder",
System.Data.OleDb.OleDbType.Integer, 0, "SortOrder"));
//
// oleDbSelectCommand1
//
this.oleDbSelectCommand1.CommandText = "SELECT
FirstName, LastName, PhoneNumber, Say, SayFileName, SortOrder, theIndex FR"
+
"OM Telephone";
this.oleDbSelectCommand1.Connection = this.cn;
//
// oleDbUpdateCommand1
//
this.oleDbUpdateCommand1.CommandText = "UPDATE
Telephone SET FirstName = ?, LastName = ?, PhoneNumber = ?, Say = ?, SayFi"
+
"leName = ?, SortOrder = ? WHERE (theIndex =
?)";
this.oleDbUpdateCommand1.Connection = this.cn;
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("FirstName",
System.Data.OleDb.OleDbType.VarWChar, 50, "FirstName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("LastName",
System.Data.OleDb.OleDbType.VarWChar, 50, "LastName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("PhoneNumber",
System.Data.OleDb.OleDbType.VarWChar, 50, "PhoneNumber"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Say",
System.Data.OleDb.OleDbType.VarWChar, 50, "Say"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SayFileName",
System.Data.OleDb.OleDbType.VarWChar, 50, "SayFileName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SortOrder",
System.Data.OleDb.OleDbType.Integer, 0, "SortOrder"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Original_theIndex",
System.Data.OleDb.OleDbType.Integer, 0,
System.Data.ParameterDirection.Input, false, ((System.Byte)(0)),
((System.Byte)(0)), "theIndex", System.Data.DataRowVersion.Original, null));

Trey said:
Of course I meant that it corrupted the data table and when I did a
DataAdapter.Update it correcupted the Database!

I have a database with this data in it for one of the tables

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- ------ --
--
1 Trey Weaver Trey say1.wav 1
2 Susan Weaver Susan say3.wav 2
3 Sam Smith Sammy say21.wav 3
4 Bill Smith Billy say4.wav
4

After doing these commands.

dr1.BeginEdit()
dr1[SortOrder} = 3;
dr1.EndEdit();
dr2.BeginEdit()
dr2[SortOrder} = 2;
dr2.EndEdit();
SaveData(); // updates the data adapter and table

The data now looks like this.

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- ------ --
--
1 Sam Smith Sammy say21.wav 2
// this is a duplicate
2 Susan Weaver Susan say3.wav 3
3 Sam Smith Sammy say21.wav 2
4 Bill Smith Billy say4.wav
4

I can set a breakpoint before and after this code check the database using
access. So I am confident that it is this code that causes the problem.

Notice that I never changed the FirstName field but yet it got changed in
the DataTable.

And Yes! I do have the datagrid connected to the dataview.


William Ryan eMVP said:
Trey:

The DataView doesn't give a hoot about the DB once you've created it. For
all it knows, the database who's data has populated it may not exist any
more. If anything is causing a corruption..it's got to be either your
update logic, some other code in the program or a corrupt database file.

I've seen this 'reported' before when people had stuff bound to a datagrid
and were using position in the grid as though it matched the underlying
datatable. That may or may not be the case based on sorting, but Something
has to send the update back to a database in order for anything to be
changed, and DataView's simply don't have that functionality. They
physically can't change a database so it's got to be your update logic..
HTH,

Bill
 
T

Trey

Here you go. (Made the wrong reply the first time)

//
// daTelephone
//
this.daTelephone.DeleteCommand =
this.oleDbDeleteCommand1;
this.daTelephone.InsertCommand =
this.oleDbInsertCommand1;
this.daTelephone.SelectCommand =
this.oleDbSelectCommand1;
this.daTelephone.TableMappings.AddRange(new
System.Data.Common.DataTableMapping[] {

new System.Data.Common.DataTableMapping("Table", "Telephone", new
System.Data.Common.DataColumnMapping[] {

new System.Data.Common.DataColumnMapping("FirstName", "FirstName"),

new System.Data.Common.DataColumnMapping("LastName", "LastName"),


new System.Data.Common.DataColumnMapping("PhoneNumber", "PhoneNumber"),

new System.Data.Common.DataColumnMapping("Say", "Say"),

new System.Data.Common.DataColumnMapping("SayFileName", "SayFileName"),

new System.Data.Common.DataColumnMapping("SortOrder", "SortOrder"),

new System.Data.Common.DataColumnMapping("theIndex", "theIndex")})});
this.daTelephone.UpdateCommand =
this.oleDbUpdateCommand1;
//
// oleDbDeleteCommand1
//
this.oleDbDeleteCommand1.CommandText = "DELETE FROM
Telephone WHERE (theIndex = ?)";
this.oleDbDeleteCommand1.Connection = this.cn;
this.oleDbDeleteCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Original_theIndex",
System.Data.OleDb.OleDbType.Integer, 0,
System.Data.ParameterDirection.Input, false, ((System.Byte)(0)),
((System.Byte)(0)), "theIndex", System.Data.DataRowVersion.Original, null));
//
// oleDbInsertCommand1
//
this.oleDbInsertCommand1.CommandText = "INSERT INTO
Telephone(FirstName, LastName, PhoneNumber, Say, SayFileName, SortOrd" +
"er) VALUES (?, ?, ?, ?, ?, ?)";
this.oleDbInsertCommand1.Connection = this.cn;
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("FirstName",
System.Data.OleDb.OleDbType.VarWChar, 50, "FirstName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("LastName",
System.Data.OleDb.OleDbType.VarWChar, 50, "LastName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("PhoneNumber",
System.Data.OleDb.OleDbType.VarWChar, 50, "PhoneNumber"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Say",
System.Data.OleDb.OleDbType.VarWChar, 50, "Say"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SayFileName",
System.Data.OleDb.OleDbType.VarWChar, 50, "SayFileName"));
this.oleDbInsertCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SortOrder",
System.Data.OleDb.OleDbType.Integer, 0, "SortOrder"));
//
// oleDbSelectCommand1
//
this.oleDbSelectCommand1.CommandText = "SELECT
FirstName, LastName, PhoneNumber, Say, SayFileName, SortOrder, theIndex FR"
+
"OM Telephone";
this.oleDbSelectCommand1.Connection = this.cn;
//
// oleDbUpdateCommand1
//
this.oleDbUpdateCommand1.CommandText = "UPDATE
Telephone SET FirstName = ?, LastName = ?, PhoneNumber = ?, Say = ?, SayFi"
+
"leName = ?, SortOrder = ? WHERE (theIndex =
?)";
this.oleDbUpdateCommand1.Connection = this.cn;
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("FirstName",
System.Data.OleDb.OleDbType.VarWChar, 50, "FirstName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("LastName",
System.Data.OleDb.OleDbType.VarWChar, 50, "LastName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("PhoneNumber",
System.Data.OleDb.OleDbType.VarWChar, 50, "PhoneNumber"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Say",
System.Data.OleDb.OleDbType.VarWChar, 50, "Say"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SayFileName",
System.Data.OleDb.OleDbType.VarWChar, 50, "SayFileName"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("SortOrder",
System.Data.OleDb.OleDbType.Integer, 0, "SortOrder"));
this.oleDbUpdateCommand1.Parameters.Add(new
System.Data.OleDb.OleDbParameter("Original_theIndex",
System.Data.OleDb.OleDbType.Integer, 0,
System.Data.ParameterDirection.Input, false, ((System.Byte)(0)),
((System.Byte)(0)), "theIndex", System.Data.DataRowVersion.Original, null));

Miha Markic said:
Hi Trey,

I read your answer to william and I wonder how is your dataadapter
configured, specially UpdateCommand.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Trey said:
I should of said after I use the DataAdapter to write the data back to the
database it is corrupt. It is really the datatable that is getting corrupt.

Miha Markic said:
Huh?
How could it corrupt the database?

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

If you have a datatable connected to a dataview.
And
In that dataview you have a "Sort" property set to a value;
And
You try to modify the "Sort" column in row in such a fashion that it gets
moved in the DataView
IT CAN
Corrupt your database.

A quick fix is to set the "Sort" property of the dataview to "" make your
changes and then set it back to it's original value.

Trey
 
T

Trey

After spending another day with this problem I think it is related to the
datagrid doing something to the dataview and then to the datatable which I
show.

So I think it may be related to the 'reported' problem with the datagrid
that you mentioned below. Do you know what the solution was to this
datagrid problem and I will try it?
 
W

William Ryan eMVP

Trey:

I just got in and am reading through your posts. let me read through it and
get back to you shortly.

Bill
 
W

William Ryan eMVP

Trey:

The issue I mention earlier isn't a bug per se, it's a matter of usage which
can be kind of confusing at first. When you first bind a Table to a grid
(or a view to a grid) then the first row of the Table DataTable.Rows(0)
corresponds exactly to the grid. So the CurrentRowIndex will match exactly.
As soon as you sort it, Row(0) for instance may end up as the 10th row of
the grid, however, it's still row(0) or the datatable. So if you use
CurrentRowIndex and you set the Row(10) of the datatable, you are going to
set something other than what you wanted to set. The 'easy' way to get
around this is to use DataGrid.IsSelected(x) (and AFAIK, you'll often have
to loop through the row) and then set the currentcell property with X as the
RowIndex and then whatever column index is. You thereby do all of your
editing with the grid and don't reference the underlying datatable at all.

In a nutshell, if your grid can be sorted, then you can't safely use
CurrentRowIndex of the grid to ever reference the table.

HTH,

Bill
 
W

William Ryan eMVP

Trey:

Is that the actual code? What is dr1 and dr2? There's some syntax errors
and I can't figure out what the underlying types should be?
Trey said:
Of course I meant that it corrupted the data table and when I did a
DataAdapter.Update it correcupted the Database!

I have a database with this data in it for one of the tables

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- ------ --
--
1 Trey Weaver Trey say1.wav 1
2 Susan Weaver Susan say3.wav 2
3 Sam Smith Sammy say21.wav 3
4 Bill Smith Billy say4.wav
4

After doing these commands.

dr1.BeginEdit()
dr1[SortOrder} = 3;
dr1.EndEdit();
dr2.BeginEdit()
dr2[SortOrder} = 2;
dr2.EndEdit();
SaveData(); // updates the data adapter and table

The data now looks like this.

id FirstName LastName Say filename SortOrder
-- ---------- ---------- ---- --------- ------ --
--
1 Sam Smith Sammy say21.wav 2
// this is a duplicate
2 Susan Weaver Susan say3.wav 3
3 Sam Smith Sammy say21.wav 2
4 Bill Smith Billy say4.wav
4

I can set a breakpoint before and after this code check the database using
access. So I am confident that it is this code that causes the problem.

Notice that I never changed the FirstName field but yet it got changed in
the DataTable.

And Yes! I do have the datagrid connected to the dataview.


William Ryan eMVP said:
Trey:

The DataView doesn't give a hoot about the DB once you've created it. For
all it knows, the database who's data has populated it may not exist any
more. If anything is causing a corruption..it's got to be either your
update logic, some other code in the program or a corrupt database file.

I've seen this 'reported' before when people had stuff bound to a datagrid
and were using position in the grid as though it matched the underlying
datatable. That may or may not be the case based on sorting, but Something
has to send the update back to a database in order for anything to be
changed, and DataView's simply don't have that functionality. They
physically can't change a database so it's got to be your update logic..
HTH,

Bill
 
T

Trey

the dr's are datarows.
SortOrder is a column (field) and should be as such ["SortOrder"}

William Ryan eMVP said:
Trey:

Is that the actual code? What is dr1 and dr2? There's some syntax errors
and I can't figure out what the underlying types should be?
---------- ---------- ---- --------- ------
--
--
1 Trey Weaver Trey say1.wav 1
2 Susan Weaver Susan say3.wav 2
3 Sam Smith Sammy say21.wav 3
4 Bill Smith Billy say4.wav
4

After doing these commands.

dr1.BeginEdit()
dr1[SortOrder} = 3;
dr1.EndEdit();
dr2.BeginEdit()
dr2[SortOrder} = 2;
dr2.EndEdit();
SaveData(); // updates the data adapter and table

The data now looks like this.

id FirstName LastName Say filename SortOrder
---------- ---------- ---- --------- ------
 

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