blog community

Welcome to blog community Sign in | Join | Help
in Search

Wouter van Vugt

This blog is no longer maintained and has moved

DataTable.Clear and rows created using NewRow()

During a course I gave some time ago, one of my students encountered a strange situation while using a DataTable. We were creating new rows for a DataTable, and not adding those rows to the Rows collection of the table, they were being set aside so to speak. During the creating of new rows, it was possible Clear was called in order to clear the table of rows. Since the rows that were set aside were not actually added to the table, we didn't expect them to be altered. But strangly it did. Two distinct DataRow objects created using NewRow() were pointing to the same piece of data, so when one was updated, so was the other.

Let's examine some of the code and determine what happened:

      DataTable table = new DataTable("Test");
      table.Columns.Add("Column1", typeof(string));
      DataRow row = table.NewRow();
      row[0] = "TestValue";
      #if SHOW_ERROR
      table.Clear();
      #endif
      DataRow otherRow = table.NewRow();
      otherRow[0] = "SomeOtherValue";
      Console.WriteLine(row[0] == otherRow[0]);

First, we create a simple DataTable, with a DataColumn. Next we create a row for the table using the NewRow() method, we also fill the row with data. Next another row is created using NewRow(), and filled as well. Notice that both rows are not added to the table, they are just created and put on the side. The compiler directive SHOW_ERROR will toggle the error, but what error exactly?

When the Clear() method is called in between two rows which have been created using NewRow(), both the first and second row will reference the same data, while we distinctly created both rows using the NewRow() method! I expect the 'row' and 'otherRow' to always store different data, but the final check will show that they are equal. Even more interesting is to compare Object.Equals(row, otherRow). This will return false!

It turns out that, when you decompile the DataRow class, that the DataRow isn't responsible for storing the data itself, the DataColumn is responsible for this. This is why Object.Equals doesn't return true (duh, 2 instances). The DataRow created using NewRow indexes a specific position in the DataColumn's data, and this index is what gets reset when calling Clear. Hence, if you call Clear between two calls to NewRow(), both rows will reference the same data.

You would expect that rows that have been created using NewRow, aren't influenced by Clear when you haven't added them to the DataTable yet. But all rows (including newly created, but un-added) reference a piece of data in the DataColumn / DataTable.

Read about this on the MSDN feedback center

Published Monday, July 18, 2005 8:09 AM by wouterv
Filed under:

Comments

 

TrackBack said:

October 1, 2005 1:03 PM
 

Fahad Iqbal said:

Experienced the same problem and it is weird! Had to do workaround of DataTable.Clone() before DataTable.NewRow() each time i want a new DataRow. Had to call the DataTable.Clear() too to avoid memory leaks as Gen 2 heap gets bigger and bigger till OutOfMemoryException
September 13, 2006 2:28 PM
 

SirRig said:

I'm trying to reference the NewRow() row, that is filled with data, to update a different row in same table. This article helped me figure out what was happening. Thanks.
May 10, 2007 1:38 AM
Anonymous comments are disabled

This Blog

Syndication

News


Add to Technorati Favorites
Powered by Community Server, by Telligent Systems