【问题标题】:C# IDataReader generic accessors across databases跨数据库的 C# IDataReader 通用访问器
【发布时间】:2012-11-10 18:19:53
【问题描述】:

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

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

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

谢谢,感谢您的回复。

【问题讨论】:

  • 只是我的两分钱,我知道您说您无权访问底层数据库架构,但我仍然认为您应该从那里开始。除非更改架构,否则我看不到避免使用条件(基于您连接到的数据库)来解决此类问题的方法。
  • 我建议为每个数据库使用不同的接口。这将确保您不会过于紧密地耦合并具有未来架构更改的灵活性。

标签: c# ado.net


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    是的,你可以。考虑到您可以将这两种类型(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 等十进制值修剪所有不需要的零。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多