将DataColumn.DataType转换为SqlDbType

C-P*_*uru 11 c# ado.net

是否有转换器从DataColumn.DataType转到SqlDbType?或者我必须写一个方法来做到这一点?

Mat*_*ler 11

这是我的解决方案,它使用内置的.NET功能:

/// <summary>
/// Get the equivalent SQL data type of the given type.
/// </summary>
/// <param name="type">Type to get the SQL type equivalent of</param>
public static SqlDbType GetSqlType(Type type)
{
    if (type == typeof(string))
        return SqlDbType.NVarChar;

    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        type = Nullable.GetUnderlyingType(type);

    var param = new SqlParameter("", Activator.CreateInstance(type));
    return param.SqlDbType;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这将始终将字符串设置为NVarChar(此问题的任何通用解决方案将具有相同的问题,因为无法知道正确的SqlDbType).当使用此参数对不是NVarChar的列进行参数化SELECT或UPDATE查询时,在将NC/NVarChar与Char/VarChar类型进行比较时,SqlServer的性能会下降,因为它正在为每次比较转换值.这最近让我很难(一个过程从4分钟到140多分钟),所以在你可以的时候总是明确你的char参数类型!我想其他类似的类型可能有相同的问题,但没有一个导致我的问题(尚).


And*_*are 6

没有现成的方法可以执行此操作 - 您需要滚动函数来执行此操作或缓存Dictionary<Type, SqlDbType>查找.


C-P*_*uru 1

我在Dot Net PulseCodeProject找到了几个选项。我最终将 CodeProject 代码从 VB.NET 转换为 C#:

private SqlDbType GetDBType(System.Type theType)
{
     System.Data.SqlClient.SqlParameter p1;
     System.ComponentModel.TypeConverter tc;
     p1 = new System.Data.SqlClient.SqlParameter();
     tc = System.ComponentModel.TypeDescriptor.GetConverter(p1.DbType);
     if (tc.CanConvertFrom(theType)) {
        p1.DbType = (DbType)tc.ConvertFrom(theType.Name);
     } else {
        //Try brute force
        try {
           p1.DbType = (DbType)tc.ConvertFrom(theType.Name);
        }
        catch (Exception) {
           //Do Nothing; will return NVarChar as default
        }
     }
     return p1.SqlDbType;
}
Run Code Online (Sandbox Code Playgroud)

我真的希望找到一些隐藏的秘密 System.Data.SqlClient 方法来进行转换,但我只是错过了它。