我在尝试使用 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 列,这是一个必需的、唯一的、键(当 PK 是一个普通的旧整数)。这种情况在源数据中确实很少见,虽然绝对不理想,但我无法修改源数据的架构。
我更详细地查看了 SchemaTable,我不知所措:
- 列名 - ID
- 列大小 - 256
- ProviderType - NVarChar
- 数据类型 - {Name = "String" FullName = "System.String"}
- IsIdentity - 真
- IsKey - 真
- IsAutoIncrement - 真
- IsUnique - 真
这对我来说没有意义。源表使用唯一代码作为 ID,虽然它不是我设计的方式,但它......很好。但我不明白 String/Varchar 如何成为身份、自动增量等。
不幸的是,我受制于这些源数据,不能乱用它,所以我希望这里的人能更深入地了解到底发生了什么。谁能想到一种方法让我在不应用 IDataReader 源数据的所有约束的情况下加载()我的 DataTable?有没有完全替代的方法可以避免这个问题?
感谢阅读,提前感谢您的帮助。这是我的第一个问题,所以要温柔。如果有更多信息对您有帮助,请告诉我!
编辑:有些人要求提供加载 DataTable 的完整代码。附于此。应该添加 CacheCommand/等。来自这个“InterSystems.Data.CacheClient”组件。有点希望这个问题可以更通用地解决。在这种情况下,查询字符串只是一个 '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:如果不清楚,我正在尝试将缓存数据库中的整个(小)表提取到数据表中。我通常通过调用 dataTable.Load(cacheDataReader) 来做到这一点,它在 99% 的情况下都可以正常工作,但是当 Cache DB 中的源表具有 VARCHAR 类型的标识列时会中断。
对我的 DataTable 对象(为空)调用 Load() 会导致它根据导入的 IDataReader(在本例中为 CacheDataReader)的结果集推断架构。问题是 CacheDataReader 中的架构指定了上面列表中的数据^,并且 DataTable 似乎不允许 MaxLength 属性,即使类型是 VARCHAR/String。