我在尝试使用IDataReader将数据加载到DataTable时遇到了一些问题。为了简单起见,我只需对命令调用ExecuteReader(),创建一个DataTable,对其调用Load(),并向其提供实现IDataReader:的对象
...
if(dataReader.HasRows)
{
DataTable tempDT = new DataTable();
tempDT.Load(dataReader);
....
}
...
这在绝大多数情况下都有效。然而,在(罕见的)情况下,我会得到以下异常(列名显然是可变的——在这种情况下,它是ID
):
Error - MaxLength applies to string data type only. You cannot set Column `ID` property MaxLength to be a non-negative number
我调查了我试图加载的源表,我怀疑问题源于它有一个VARCHAR(256)ID列,即Required,Unique,Key(当PK是常规的旧int时,问题似乎不会发生)。这种类型的情况在源数据中非常罕见,虽然它绝对不是理想的,但我无法修改源数据的模式。
我更详细地查看了SchemaTable,我不知所措:
- 列名称-ID
- 列大小-256
- ProviderType-NVarChar
- DataType-{Name="String"FullName="System.String"}
- IsIdentity-True
- IsKey-True
- IsAutoIncrement-True
- IsUnique-True
这对我来说毫无意义。源表使用唯一的代码作为ID,虽然这不是我设计它的方式,但它确实是。。好的但我不明白String/Varchar是如何成为一个身份、自动增量等的。
不幸的是,我受这个源数据的支配,无法处理它,所以我希望这里的人能更深入地了解到底发生了什么。有人能想出一种方法让我在不应用IDataReader源数据的所有约束的情况下加载()我的DataTable吗?有没有一种完全替代的方法可以避免这个问题?
感谢阅读,提前感谢您的帮助。这是我的第一个问题,所以要温柔。如果还有任何有用的信息,请告诉我!
编辑:有些人要求提供加载DataTable的完整代码。附于此。应该添加CacheCommand/等。来自此"InterSystem.Data.CacheClient"密码。有点希望这个问题可以更普遍地解决。在这种情况下,Query字符串只是一个"SELECT TOP 10*"测试。
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;
}
}
}
}
编辑2:如果不清楚,我将尝试将整个(小)表从Cache DB提取到DataTable中。我通常通过调用dataTable.Load(cacheDataReader)来实现这一点,它99%的时间都能正常工作,但当Cache DB中的源表具有VARCHAR类型的标识列时,它就会中断。
对我的DataTable对象(为空)调用Load()会使它根据导入的IDataReader(在本例中为CacheDataReader)的结果集推断架构。问题是,CacheDataReader中的架构指定了上面^列表中的数据,而DataTable似乎不允许使用MaxLength属性,即使类型是VARCHAR/String。
SELECT TOP 10 * FROM table
WHERE IsNumeric(ColumName) = 0
这将只返回主键类型为Int 的数据