C# Odbc使用internalGetDate将字符串解析为日期?

C# Odbc使用internalGetDate将字符串解析为日期?,c#,.net-4.0,odbc,C#,.net 4.0,Odbc,我正在尝试将我为SQL Server连接编写的一段代码转换为使用Odbc数据源。我在OdbcDataReader.GetValue(int)试图为字符串字段调用OdbcDataReader.internalGetDate时遇到了一些问题 以下是我当前用于获取值的代码: private static void ReadRecord<T>(IDataRecord record, T myClass) { .... inside loop of datarecord fields

我正在尝试将我为SQL Server连接编写的一段代码转换为使用Odbc数据源。我在OdbcDataReader.GetValue(int)试图为字符串字段调用OdbcDataReader.internalGetDate时遇到了一些问题

以下是我当前用于获取值的代码:

private static void ReadRecord<T>(IDataRecord record, T myClass)
{
    .... inside loop of datarecord fields ....
        var value = record.GetValue(i);
        pi.SetValue(myClass,
            value == DBNull.Value
                ? null
                : Convert.ChangeType(value, record.GetFieldType(i)), null);
我查看了参考源代码,它显示执行GetSqlType是为了确定在以后的GetValue()调用中要调用的函数。我编写这段代码是为了检查相关索引的SqlType

var odbcdatareader = typeof(OdbcDataReader);
var method = odbcdatareader.GetMethod("GetSqlType", BindingFlags.Instance | BindingFlags.NonPublic);
var type = method.Invoke(record, new object[] { i });
var typemap = odbcdatareader.Assembly.GetType("System.Data.Odbc.TypeMap");
var typemapodbctype = typemap.GetField("_odbcType", BindingFlags.Instance | BindingFlags.NonPublic);
var typemapdbtype = typemap.GetField("_dbType", BindingFlags.Instance | BindingFlags.NonPublic);
var typemaptype = typemap.GetField("_type", BindingFlags.Instance | BindingFlags.NonPublic);
var typemapsqltype = typemap.GetField("_sql_type", BindingFlags.Instance | BindingFlags.NonPublic);

Console.WriteLine("{0}, {1}, {2}, {3}", typemapodbctype.GetValue(type),
    typemapdbtype.GetValue(type), typemaptype.GetValue(type),
    typemapsqltype.GetValue(type));
检查结果如下:

Char, AnsiStringFixedLength, System.String, CHAR
为什么Odbc的GetSqlType会将其作为一个字符报告,然后使用internalGetDate尝试解析数据?我错过了什么明显的东西吗

更奇怪的是,当我在该索引上调用GetString()时,internalGetDate()也会出错


此问题实际上与另一个问题有关,其中数据库服务器(在本例中为4D)将空日期关联为00/00/0000 12:00:00 AM。DateTime无法解析此日期,因此OdbcDataReader崩溃。我通过捕获异常并将类的属性设置为null解决了第一个问题,但这并没有解决根本问题。DbCache没有缓存该值,因为出现了异常,并且由于如何缓存,系统必须在每个字段上循环并获取其数据。这就是潜在的错误。GetString在0..i之间循环,并在i-1字段的internalGetDate上崩溃

决议是。。。。在我看来很难看,但对我来说很有用

catch (ArgumentOutOfRangeException ex)
{
    if (ex.Message == "Year, Month, and Day parameters describe an un-representable DateTime.")
    {
        pi.SetValue(myClass, null, null);
        var odbcdatareader = typeof(OdbcDataReader);
        var dataCache = odbcdatareader.GetField("dataCache",
            BindingFlags.Instance | BindingFlags.NonPublic);
        var dbcache = dataCache.GetValue(record);
        var valuesfield = dbcache.GetType()
            .GetField("_values", BindingFlags.Instance | BindingFlags.NonPublic);
        var values = (object[]) valuesfield.GetValue(dbcache);
        values[i] = new DateTime(1, 1, 1);
        valuesfield.SetValue(dbcache, values);
    }
    else
        throw;
}

问题。。您正在通过ODBC访问哪种类型的数据库。。?这是Sql Server吗。。?如果是这样,为什么不离开
System.Data.Odbc
对象,使用SqlClient数据对象呢。。
at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)
at System.Data.Odbc.OdbcDataReader.GetData(Int32 i, SQL_C sqlctype, Int32 cb, Int32& cbLengthOrIndicator)
at System.Data.Odbc.OdbcDataReader.GetData(Int32 i, SQL_C sqlctype)
at System.Data.Odbc.OdbcDataReader.internalGetDate(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i, TypeMap typemap)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
at System.Data.Odbc.DbCache.AccessIndex(Int32 i)
at System.Data.Odbc.OdbcDataReader.internalGetString(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetString(Int32 i)
catch (ArgumentOutOfRangeException ex)
{
    if (ex.Message == "Year, Month, and Day parameters describe an un-representable DateTime.")
    {
        pi.SetValue(myClass, null, null);
        var odbcdatareader = typeof(OdbcDataReader);
        var dataCache = odbcdatareader.GetField("dataCache",
            BindingFlags.Instance | BindingFlags.NonPublic);
        var dbcache = dataCache.GetValue(record);
        var valuesfield = dbcache.GetType()
            .GetField("_values", BindingFlags.Instance | BindingFlags.NonPublic);
        var values = (object[]) valuesfield.GetValue(dbcache);
        values[i] = new DateTime(1, 1, 1);
        valuesfield.SetValue(dbcache, values);
    }
    else
        throw;
}