2011-06-14 76 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。正確的映射是爲你自動完成:)