Wednesday, August 17, 2011

Weird 'DataTableReader is invalid for current DataTable' exception

I was debugging an application when I've noticed that there was an exception thrown in one of the legacy DAL modules. A method was using regular ADO.Net to run a stored procedure, fill a DataSet, then proceeded on getting an IDataReader for the set, using the CreateDataReader method. On reader.Read() the exception DataTableReader is invalid for current DataTable 'Table' was thrown.

I've investigated the issue only to notice that the DataSet was correctly retrieved from the database, the only problem came when creating the reader. Any meaningful property threw this error. I've found a thread that discussed this problem here, but the answer was not there. Instead, I read an obscure line somewhere that said this exception is thrown when the DataSet has changes and tried that solution: before running CreateDataReader, I ran DataSet.AcceptChanges. And it worked!

The strange part comes now: I did the AcceptChanges bit in the Watch window during debug, not as a permanent change to the code. From then on, the code worked, no matter how many times I ran iisreset or restarted the browser. I've added the solution in the code for good measure, but I am still not sure if this is the solution or simply some fluke of the universe. One possible answer is the "race condition" described in this discussion, which also suggests this happens in debug mode only. Strange, innit?

Update: AcceptChanges did not solve the issue on the production server. I am still investigating, but if you know what this is about, please share :)


Anonymous said...

Just thought I would post on here in case it's helps someone else. I tried a number of things and in the end i simply changed the name of the datareader and it worked! i dont know why for sure but i think it might be because the datareaders (originally) werent being closed, so maybe after a few times debugging, there was lots of "stuff" in memory with a certain name attached and it said "no more!". still, i could be talking bullpies. my advice, change the name of your datareader variable and make sure you close it after you use it

Fabio said...

To avoid this error try to include a just before to
return a column value, also if datareader has only one row.

Siderite said...

Thank you, Fabio! I've met a situation just like that a few days ago. But then the error is completely reproducible, whether in debug mode or not. My original case was not like that.

As a side note, based on my experience a few days ago, if a query returns more than one result set, the DataTableReader command needed to move to the next result set is NextResult(). You also need to do a Read() afterwards, else you get the error in the title.

Anonymous said...

1Gb Thanks! :)