0

我正在开发一个需要使用“相似”模式连接到不同数据库类型(SQL Server、Oracle、DB2)的应用程序。我说“相似”模式是因为表名、列等......是相同的,但底层数据类型特定于该数据库类型。例如,在 SQL Server 和 Oracle 数据库中,我都有一个名为“tablename”的表和一个名为“column”的列。'column' 的数据类型对于 Oracle 是 NUMBER,对于 SQL Server 是 float。

我可以通过通用 ADO 接口获取适当的提供程序工厂、连接和查询,但我不确定并且遇到问题的是我应该如何访问此列。

对于 Oracle,我相信我应该对 NUMBER 数据类型字段使用访问器函数“GetDecimal()”,事实上,似乎使用任何其他访问器,例如 GetInt32()、GetDouble(),我都会遇到强制转换异常。对于 SQL Server,我应该使用访问器函数“GetDouble()”。无论底层数据库数据类型如何,是否有一种方法/策略可以使用单个访问器函数获取此值?请注意,我无法控制后端数据库架构。

谢谢,我很感激回复。

4

2 回答 2

0

您可以使用 IDataReader.GetValue 但您仍然需要在某个地方进行投射。您可以将访问抽象到一个通用包装器中,并在数据读取器上使用 GetSchemaTable 作为一种机制,以就将 GetValue 的结果转换为什么做出明智的决定。

于 2012-07-31T03:56:25.443 回答
0

是的你可以。考虑到您可以将两种类型(SqlServer 的浮点数和 Oracel 的数量)转换为像十进制这样的 .NET 数据类型,您可以依赖System.Convert类中的方法。你实际上应该这样做:

internal static decimal Read(IDbCommand cmd)
{
    cmd.CommandText = @"SELECT column FROM tablename LIMIT 1";
    using (var r = cmd.ExecuteReader())
    {
        while(r.Read())
        {
            return Convert.ToDecimal(r[0]);
            //instead of return r.GetDecimal(0);

            //or even better return r[0].ToFormattedDecimal();
        }
    }
}

public static decimal ToFormattedDecimal(this object d)
{
    if (d is DBNull || d == null) //important line - to check DbNull
        return 0; //your value

    try
    {
        return Convert.ToDecimal(d).Normalize();
    }
    catch (Exception ex)
    {
        throw ex;
        // or may be return 0;
    }
}

public static decimal Normalize(this decimal d)
{
    return d / 1.00000000000000000000000000000m;
}

我写了一个扩展方法来让你的工作更轻松。该Normalize函数会在末尾修剪所有不需要的零,以获取诸如 23.0000 等十进制值。

于 2012-11-10T10:19:53.867 回答