当IDataReader源具有VARCHAR(256)标识列

时间:2016-01-12 19:58:43

标签: c# .net intersystems-cache idatareader

我在尝试使用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是一个常规的老int)。这种情况在源数据中并不常见,虽然它绝对不是理想,但我无法修改源数据的模式。

我更详细地看了一下SchemaTable,我很茫然:

  • ColumName - ID
  • ColumnSize - 256
  • ProviderType - NVarChar
  • DataType - {Name =“String”FullName =“System.String”}
  • IsIdentity - True
  • IsKey - True
  • IsAutoIncrement - True
  • IsUnique - True

这对我来说没有意义。源表使用唯一代码作为ID,虽然它不是我设计它的方式,但它很好。但我不明白String / Varchar如何永远成为身份,自动增量等。

不幸的是,我受这些源数据的支配并且不能搞砸它,所以我希望这里有人可以更深入地了解究竟发生了什么。任何人都可以为我设想一种方法来加载我的DataTable 而不用应用IDataReader源数据中的所有约束?是否存在可以避免此问题的完全替代方法?

感谢您的阅读,提前感谢您的帮助。这是我的第一个问题,所以要温柔。如果有更多信息可以提供帮助,请告诉我们!

编辑:有些人要求提供加载DataTable的完整代码。附在这里。应该添加CacheCommand / etc。来自这个'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:如果不清楚,我正在尝试从Cache DB中将整个(小)表提取到DataTable中。我通常通过调用dataTable.Load(cacheDataReader)来做到这一点,它在99%的情况下工作正常,但是当Cache DB中的源表具有VARCHAR类型的标识列时会中断。

在我的DataTable对象(为空)上调用Load()会导致它根据导入的IDataReader(在本例中为CacheDataReader)中的结果集来推断架构。问题是CacheDataReader中的模式指定了^上面列表中的数据,而DataTable似乎不允许MaxLength属性,即使类型是VARCHAR / String。

1 个答案:

答案 0 :(得分:0)

SELECT TOP 10 * FROM table
WHERE IsNumeric(ColumName) = 0 

这将仅返回主键类型为Int

的数据