Skip to content
Advertisement

DataTable ‘Table’ already belongs to this DataSet – on a new DataSet?

I have a function that executes SQL queries and returns a generic DataSet of the query results. This function has been working for years in many applications, but today with a specific query I am getting

“Error executing [select top (1) RecordId, SourceCID, SourceID, CaseID, DisposeRequestedDate, DisposeRequestedBy, DisposeApprovedDate, DisposeApprovedBy from mycatalog.dbo.CASD_RetentionManagementDisposalApprovedQueue order by DisposeApprovedDate, RecordID;] A DataTable named ‘Table’ already belongs to this DataSet.”

The function is

The calling procedure is basically:

When my configuration parameter is set to 1 (Select top (1) …), I get the error. When set to 2, (Select top (2) …), the error does not occur. Is there something unique about “Select top (1)…” or am I doing something wrong? BTW – the table is currently empty, so neither top 1 nor top 2 should return any rows.

As requested – the IsValidDataSet and IsValidButEmptyDataSet methods:

As requested – Stack Trace from error: Stack trace: at System.Data.DataTableCollection.RegisterName(String name, String tbNamespace) at System.Data.DataTableCollection.BaseAdd(DataTable table) at System.Data.DataTableCollection.Add(DataTable table) at System.Data.ProviderBase.SchemaMapping.SetupSchemaWithoutKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, Boolean gettingData, DataColumn parentChapterColumn, Object chapterValue) at System.Data.ProviderBase.SchemaMapping..ctor(DataAdapter adapter, DataSet dataset, DataTable datatable, DataReaderContainer dataReader, Boolean keyInfo, SchemaType schemaType, String sourceTableName, Boolean gettingData, DataColumn parentChapterColumn, Object parentChapterValue) at System.Data.Common.DataAdapter.FillMappingInternal(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue) at System.Data.Common.DataAdapter.FillMapping(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue) at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue) at System.Data.Common.DataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet) at SQLUtility.ExecSQLQuery(String sqlQuery, Boolean ignoreError)

Advertisement

Answer

I believe I have figured out what is happening.
My ExecSQLQuery method is not thread-safe (it is a public static method), but I have two independent timers running. If timer 2 fires while the timer 1 process sequence is currently executing inside this method, the second can wind up making a call to this same procedure. When the timer 2 process terminates, the first code resumes, BUT the local variables are now already loaded, resulting in the “‘Table’ already belongs to the DataSet” error. I added a lot of diagnostic code and found that this was happening only after a lot of executions from both timers firing. I will add a semaphore to prevent one process from executing while the other is already executing.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement