2011-06-14 74 views
1

所以,我有以下几点:"SELECT * FROM MyTable;"C#:映射IDataReader.GetTableSchema()和DbType枚举?

当我做了以下我得到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(); 

现在,遍历我的桌子时,我遇到了一个名为“数据类型”列,它要么是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?) 

基本上,我怎样才能得到表的真正模式......或者它甚至是重要的?

回答

1

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

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

您使用的是IDbCommand的,而不是SqlCommand的使用

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

命令

编辑。我知道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

+0

我没有使用SqlCommand。我的类型是'IDbCommand'类型。而在IDbCommand中,您无法执行command.Parameters.AddWithValue(...);只有command.Parameters.Add()是因为command.Parameters是IDataParameterCollection类型。 – michael 2011-06-14 13:56:44

+0

NB有点正确。您不需要明确设置DbType,只需将值传入。但是,您也是正确的。 IDbCommand.Parameters没有AddWithValue方法。看到我的回答如下... – 2011-06-14 14:06:52

+0

我的不好!接口没有指定这种区别。我知道SqlCommand和OracleCommand对象都不需要定义的DbType。但是......我不知道可能需要它们的其他实现。我已经用相应的方法更新了我的答案。 – 2011-06-14 14:19:39

1
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。正确的映射是为你自动完成:)