Подтвердить что ты не робот

Преобразование DataColumn.DataType в SqlDbType

Есть ли конвертер для перехода от DataColumn.DataType к SqlDbType? Или мне нужно написать метод для этого?

4b9b3361

Ответ 1

Я нашел пару опций Dot Net Pulse и CodeProject. В итоге я пошел с кодом CodeProject, преобразованным из VB.NET в С#:

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;
}

Я действительно надеялся найти, что есть какой-то скрытый секретный метод System.Data.SqlClient для преобразования, и я просто пропустил его.

Ответ 2

Здесь мое решение, которое использует встроенную функциональность .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;
}

Остерегайтесь того, что это всегда задает строки для NVarChar (любое общее решение этой проблемы будет иметь одинаковую ошибку, потому что нет способа узнать правильный SqlDbType). При использовании этого параметра для параметризованных запросов SELECT или UPDATE для столбцов, которые не являются NVarChar, производительность SqlServer затягивается при сравнении типов NChar/NVarChar с типами Char/VarChar, потому что они преобразуют значения для каждого сравнения. Это немного изменило меня в последнее время (процесс прошел от 4 минут до 140 + минут), поэтому всегда будьте откровенны в отношении типов параметров char, когда сможете! Я бы предположил, что у других подобных типов может быть одна и та же проблема, но ни одна из них не вызвала у меня проблемы (пока).

Ответ 3

Нет существующих методов для этого - вам нужно будет свернуть функцию, чтобы сделать это, или кешировать Dictionary<Type, SqlDbType> для поиска.

Ответ 4

Что-то вроде этого может быть хорошим началом. Это не всеобъемлющее, но привело меня туда, куда мне нужно было идти:

Dictionary<Type, SqlDbType> GetSQLTypeConversionMap()
{
    var result = new Dictionary<Type, SqlDbType>();
    result.Add(typeof(string), SqlDbType.VarChar);
    result.Add(typeof(Int16), SqlDbType.Int);
    result.Add(typeof(Int32), SqlDbType.Int);
    result.Add(typeof(DateTime), SqlDbType.DateTime2);
    return result;  
}

Ответ 5

Вы можете скопировать DataTable, например

DataTable newdt = DataTable.Copy();

И удалите столбцы с различными DataTypes и добавьте их в свой newdt.

Только один способ, которым я работал в прошлом.

Ответ 6

Ответил в этот поток, но он довольно краток, поэтому я перепишу его здесь:

Вы можете преобразовать TypeCode в DbType с помощью метода ConvertTypeCodeToDbType в классе System.Web.UI.WebControls.Parameter: Parameter.ConvertTypeCodeToDbType Метод. Чтобы получить TypeCode, вы можете использовать метод Type.GetTypeCode(Type type).