连接TypeCode和SqlDbType或DbType

本文关键字:DbType SqlDbType TypeCode 连接 | 更新日期: 2023-09-27 18:11:55

是否有一种方法可以链接TypeCode枚举和SqlDbType枚举。我计划,当任何类型的c - sharp中的特定变量标识其TypeCode时,我有相应的SqlDbType。我需要在我的数据库中创建表,以满足我的要求。T.I.A

连接TypeCode和SqlDbType或DbType

这里有一个获取任何给定对象的SqlDbType值的技巧。(它不是基于TypeCode):

// create an SQL Parameter object
SqlParameter p = new SqlParameter("dummy", myObj);
// ask SQL code to compute its SqlDbType for us
Console.WriteLine(p.SqlDbType);

必须处理一个通用的DbCommand,它可以是SqlCommand或MySqlDbCommand,我创建了这个结构:

static readonly (Type type, DbType dbType, SqlDbType sqlDbType, MySqlDbType mySqlDbType)[] dbTypesRosetta = new[]
{
    (typeof(string), DbType.String, SqlDbType.VarChar, MySqlDbType.VarString),
    (typeof(string), DbType.String, SqlDbType.Text, MySqlDbType.LongText),
    (typeof(string), DbType.String, SqlDbType.Char, MySqlDbType.String),
    (typeof(char), DbType.StringFixedLength, SqlDbType.Char, MySqlDbType.String),
    (typeof(byte), DbType.Byte, SqlDbType.TinyInt, MySqlDbType.Byte),
    (typeof(short), DbType.Int16, SqlDbType.SmallInt, MySqlDbType.Int16),
    (typeof(int), DbType.Int32, SqlDbType.Int, MySqlDbType.Int32),
    (typeof(long), DbType.Int64, SqlDbType.BigInt, MySqlDbType.Int64),
    (typeof(byte[]), DbType.Binary, SqlDbType.Image, MySqlDbType.LongBlob), //Up to 8000 bytes for DbType
    (typeof(bool), DbType.Boolean, SqlDbType.Bit, MySqlDbType.Bit),
    (typeof(decimal), DbType.Currency, SqlDbType.Money, MySqlDbType.Decimal),
    (typeof(decimal), DbType.Decimal, SqlDbType.Decimal, MySqlDbType.Decimal),
    (typeof(float), DbType.Single, SqlDbType.Real, MySqlDbType.Float),
    (typeof(double), DbType.Double, SqlDbType.Float, MySqlDbType.Double),
    (typeof(TimeSpan), DbType.Time, SqlDbType.Time, MySqlDbType.Time),
    (typeof(DateTime), DbType.DateTime, SqlDbType.DateTime, MySqlDbType.DateTime),
    (typeof(DateTime), DbType.Date, SqlDbType.Date, MySqlDbType.Date),
    (typeof(DateTimeOffset), DbType.DateTimeOffset, SqlDbType.DateTimeOffset, MySqlDbType.DateTime),
    (typeof(byte[]), DbType.Binary, SqlDbType.Timestamp, MySqlDbType.Binary),
    (typeof(Guid), DbType.Guid, SqlDbType.UniqueIdentifier, MySqlDbType.Guid)
};

在源"列"上线性扫描元组列表,在第一次出现时,我可以找到所有(大部分)对应的等效类型

可以这样使用:

string s;
SqlDbType t = dbTypesRosetta.First(map => map.type == typeof(s)).sqlDbType;
//OR
MySqlDbType t = dbTypesRosetta.First(map => map.sqlDbType == SqlDbType.Int32).mySqlDbType;
//OR for creating a method like this:
public static DbCommand SetParamOutput<T>(this DbCommand cmd, string paramName, out DbParameter paramOutput)
    => SetParamOutput(cmd, paramName, dbTypesRosetta.First(map => map.type == typeof(T)).dbType, out paramOutput);

它实际上是一个罗塞塔石碑;))))

下面的方法将TypeCode转换为相应的SqlDbType

如果TypeCode不能被映射,error = true;

public static SqlDbType Typecode2SqlDbType(TypeCode typecode, out bool error)
{
    error=false;
    switch (typecode)
    {
        case TypeCode.Empty     :
             return SqlDbType.Variant   ;
        case TypeCode.Object    :
             return SqlDbType.Variant   ;
        case TypeCode.DBNull    :
             return SqlDbType.Variant   ;
        case TypeCode.Boolean   :
             return SqlDbType.Bit       ;
        case TypeCode.Char      :
             return SqlDbType.NChar     ;
        case TypeCode.Byte      :
             return SqlDbType.TinyInt   ;
        case TypeCode.Int16     :
             return SqlDbType.SmallInt  ;
        case TypeCode.Int32     :
             return SqlDbType.Int       ;
        case TypeCode.Int64     :
             return SqlDbType.BigInt    ;
        case TypeCode.Single    :
             return SqlDbType.Real      ;
        case TypeCode.Double    :
             return SqlDbType.Float     ;
        case TypeCode.Decimal   :
             return SqlDbType.Decimal   ;
        case TypeCode.DateTime  :
             return SqlDbType.DateTime  ;
        case TypeCode.String    :
             return SqlDbType.NVarChar  ;
        // can't map TypeCode.SByte  
        // can't map TypeCode.UInt16  
        // can't map TypeCode.UInt32  
        // can't map TypeCode.UInt64  
        default:
        {
            error =true;
            return SqlDbType.NVarChar;
        }
    }
}

}