【问题标题】:C#: Mapping the IDataReader.GetTableSchema() and DbType Enumeration?C#:映射 IDataReader.GetTableSchema() 和 DbType 枚举?
【发布时间】:2011-06-14 13:34:10
【问题描述】:

所以,我有以下内容:"SELECT * FROM MyTable;"

当我执行以下操作时,我得到了 TableData,这很有用,但仍然留下一些未知的东西?

//CommandBehavior.KeyInfo seems to actually return the correct primary keys
// not so much with CommandBehavior.SchemaOnly.
IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo)

DataTable table = reader.GetSchemaTable();

现在,当迭代我的表时,我遇到了一个名为“DataType”的列,它是 System.String 或 System.Byte[] 或 System.Int32 等。但是,这只会告诉我 .NET 类型商店,它不会告诉我,例如,System.DecimalDbType.Currency 还是DbType.Decimal。因此,当我创建 IDataParameter 时,我不确定要为 DbType 设置什么。

parameter.ColumnName = columnName;
parameter.DbType = DbType.Decimal; (or should it have been Currency?)

基本上,我怎样才能获得表的真实架构......或者它甚至重要吗?

【问题讨论】:

    标签: c# database database-schema query-parameters dbtype


    【解决方案1】:

    如果您是为存储过程或一些 sql 文本传入参数,则不需要指定参数数据类型。 SqlCommand 将为您正确分配数据类型。

    我相信在参数上分配 DBType 的能力是如果您想覆盖系统会为您选择的内容。

    使用

    SqlCommand.Parameters.AddWithValue("@parameterName", valueAsObject);
    

    命令

    edit您使用的是 IDbCommand,而不是 SqlCommand。我知道 SqlCommand 和 Oracle 命令都不需要你指定 DbType,但我不知道其他框架是否需要你显式设置 DbType。这是一种将 system.type 转换为 DbType 枚举值的方法:

    Class DBTypeConversion
    {
        private static String[,] DBTypeConversionKey = new String[,] 
        {
         {"BigInt","System.Int64"},
         {"Binary","System.Byte[]"},
         {"Bit","System.Boolean"},
         {"Char","System.String"},
         {"DateTime","System.DateTime"},
         {"Decimal","System.Decimal"},
         {"Float","System.Double"},
         {"Image","System.Byte[]"},
         {"Int","System.Int32"},
         {"Money","System.Decimal"},
         {"NChar","System.String"},
         {"NText","System.String"},
         {"NVarChar","System.String"},
         {"Real","System.Single"},
         {"SmallDateTime","System.DateTime"},
         {"SmallInt","System.Int16"},
         {"SmallMoney","System.Decimal"},
         {"Text","System.String"},
         {"Timestamp","System.DateTime"},
         {"TinyInt","System.Byte"},
         {"UniqueIdentifer","System.Guid"},
         {"VarBinary","System.Byte[]"},
         {"VarChar","System.String"},
         {"Variant","System.Object"}
        };
    
    
        public static SqlDbType SystemTypeToDbType( System.Type sourceType )
        {
        SqlDbType result;
        String SystemType = sourceType.ToString();
        String DBType = String.Empty;
        int keyCount = DBTypeConversionKey.GetLength(0);
    
        for(int i=0;i<keyCount;i++)
        {
        if(DBTypeConversionKey[i,1].Equals(SystemType)) DBType = DBTypeConversionKey[i,0];
        }
    
        if (DBType==String.Empty) DBType = "Variant";
    
        result = (SqlDbType)Enum.Parse(typeof(SqlDbType), DBType);
    
        return result;
        }
    
        public static Type DbTypeToSystemType( SqlDbType sourceType )
        {
        Type result;
        String SystemType = String.Empty;
        String DBType = sourceType.ToString();
        int keyCount = DBTypeConversionKey.GetLength(0);
    
        for(int i=0;i<keyCount;i++)
        {
        if(DBTypeConversionKey[i,0].Equals(DBType)) SystemType = DBTypeConversionKey[i,1];
        }
    
        if (SystemType==String.Empty) SystemType = "System.Object";
    
        result = Type.GetType(SystemType);
    
        return result;
        }
    

    http://social.msdn.microsoft.com/Forums/en/winforms/thread/c6f3ab91-2198-402a-9a18-66ce442333a6 希望这有助于更好地澄清。

    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparametercollection.addwithvalue.aspx

    【讨论】:

    • 我没有使用 SqlCommand。我的类型是IDbCommand。而在 IDbCommand 你不能做 command.Parameters.AddWithValue(...);只有 command.Parameters.Add(),因为 command.Parameters 的类型是 IDataParameterCollection。
    • NB 有些正确。您不需要显式设置 DbType,只需将值传入即可。但是,您也是正确的。 IDbCommand.Parameters 没有 AddWithValue 方法。请参阅下面的答案...
    • 我的错!接口没有指定这种区别。我知道 SqlCommand 和 OracleCommand 对象都不需要定义 DbType。但是...我不知道可能需要它们的其他实现。我已经用相应的方法更新了我的答案。
    • @NB:整个转换器映射不会解决任何问题,因为我仍然想知道是否应该将 System.Decimal 映射到 DbType.Decimal 或 DbType.Currency。但是,你是对的。我会让驱动程序决定将我的 System.Decimal 映射到什么。
    • 啊,是的,十进制数据类型非常令人困惑,因为 SQL Server 中的十进制定义了一个精度范围(句点前后的位数),而 .net 十进制在可变精度方面更加灵活.我会编写一些边界单元测试,以确保 .net 框架按照您的预期处理精度。
    【解决方案2】:
    IDbCommand command = GetCommand(); //However you want to implement it.
    
    IDbDataParameter param = command.CreateParameter();
    //Or some other method that returns a parameter.
    
    command.Parameters.Add(param);
    param.Value = thevalue; //You're value here!
    

    遗憾的是,如果您使用 IDbCommand,则无法在一行中完成。你不能做类似command.Parameters.Add(param).Value = thevalue;

    另外,您确实需要设置参数的DbType。正确的映射会自动为您完成 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 2017-03-03
      相关资源
      最近更新 更多