I'm running into some trouble trying to load data into a DataTable using an IDataReader. To keep it really simple, I just call ExecuteReader() on the command, create a DataTable, call Load() on it and feed it the object implementing IDataReader:
...
if(dataReader.HasRows)
{
DataTable tempDT = new DataTable();
tempDT.Load(dataReader);
....
}
...
This works in the vast majority of cases. However, in (rare) circumstances, I get the following exception (column name is obviously variable - in this case, it's ID
):
Error - MaxLength applies to string data type only. You cannot set Column `ID` property MaxLength to be a non-negative number
I investigated the source table I was trying to load, and I suspect that the problem stems from it having a VARCHAR(256) ID column, that is a Required, Unique, Key (the issue doesn't seem to occur when the PK is a regular old int). This type of situation is really uncommon in the source data, and while it definitely isn't ideal, I can't modify the schema of the source data.
I took a look at the SchemaTable in more detail, and I am at a loss:
- ColumName - ID
- ColumnSize - 256
- ProviderType - NVarChar
- DataType - {Name = "String" FullName = "System.String"}
- IsIdentity - True
- IsKey - True
- IsAutoIncrement - True
- IsUnique - True
It just doesn't make sense to me. The source table uses unique codes as the ID, and while it isn't the way I would've designed it, it's.. fine. But I don't understand how a String/Varchar can ever be an identity, auto-increment, etc.
Unfortunately, I'm at the mercy of this source data and can't mess with it, so I'm hoping someone here might have more insight into what exactly is going on. Can anyone conceive of a way for me to Load() my DataTable without applying all the constraints from the IDataReader source data? Is there an entirely alternative approach that would avoid this problem?
Thanks for reading, thanks in advance for any assistance. It's my first question so be gentle. If there's any more information that would help, please let me know!
EDIT: Some people asked for the full code for loading the DataTable. Appended here. Should add that the CacheCommand/etc. comes in from this 'InterSystems.Data.CacheClient' assm. Kinda hoping the problem can be approached more generically. In this case, the Query string is just a 'SELECT TOP 10 *' test.
using (CacheConnection cacheConnection = new CacheConnection())
{
cacheConnection.ConnectionString = connectionString;
cacheConnection.Open();
using (CacheCommand cacheCommand = new CacheCommand(Query, cacheConnection))
{
using (CacheDataReader cacheDataReader = cacheCommand.ExecuteReader())
{
if (cacheDataReader.HasRows)
{
DataTable tempDT = new DataTable();
tempDT.Load(cacheDataReader); // Exception thrown here.
cacheConnection.Close();
return tempDT;
}
else
{
cacheConnection.Close();
return null;
}
}
}
}
EDIT 2: In case it's not clear, I'm trying to extract the entirety of a (small) table from the Cache DB into a DataTable. I normally do this by calling dataTable.Load(cacheDataReader), which works fine 99% of the time, but breaks when the source table in the Cache DB has an identity column of type VARCHAR.
Calling Load() on my DataTable object (which is empty) causes it to infer the schema based on the result set from the imported IDataReader (in this case, CacheDataReader). The problem is that the schema in the CacheDataReader specifies the data in the list above^, and DataTable doesn't seem to allow the MaxLength property, even though the type is VARCHAR/String.