简体   繁体   English

如何将 System.Type 解析为 System.Data.DbType?

[英]How to resolve System.Type to System.Data.DbType?

在 System 命名空间中查找基类库类型的System.Data.DbType枚举值的最佳方法是什么?

A common way is to have a type map, with all supported types ( different connectors/providers supports different types ) explicitly mapped.一种常见的方法是使用类型映射,显式映射所有支持的类型(不同的连接器/提供程序支持不同的类型)。 Here is the type map for Dapper :这是Dapper的类型映射:

typeMap = new Dictionary<Type, DbType>();
typeMap[typeof(byte)] = DbType.Byte;
typeMap[typeof(sbyte)] = DbType.SByte;
typeMap[typeof(short)] = DbType.Int16;
typeMap[typeof(ushort)] = DbType.UInt16;
typeMap[typeof(int)] = DbType.Int32;
typeMap[typeof(uint)] = DbType.UInt32;
typeMap[typeof(long)] = DbType.Int64;
typeMap[typeof(ulong)] = DbType.UInt64;
typeMap[typeof(float)] = DbType.Single;
typeMap[typeof(double)] = DbType.Double;
typeMap[typeof(decimal)] = DbType.Decimal;
typeMap[typeof(bool)] = DbType.Boolean;
typeMap[typeof(string)] = DbType.String;
typeMap[typeof(char)] = DbType.StringFixedLength;
typeMap[typeof(Guid)] = DbType.Guid;
typeMap[typeof(DateTime)] = DbType.DateTime;
typeMap[typeof(DateTimeOffset)] = DbType.DateTimeOffset;
typeMap[typeof(byte[])] = DbType.Binary;
typeMap[typeof(byte?)] = DbType.Byte;
typeMap[typeof(sbyte?)] = DbType.SByte;
typeMap[typeof(short?)] = DbType.Int16;
typeMap[typeof(ushort?)] = DbType.UInt16;
typeMap[typeof(int?)] = DbType.Int32;
typeMap[typeof(uint?)] = DbType.UInt32;
typeMap[typeof(long?)] = DbType.Int64;
typeMap[typeof(ulong?)] = DbType.UInt64;
typeMap[typeof(float?)] = DbType.Single;
typeMap[typeof(double?)] = DbType.Double;
typeMap[typeof(decimal?)] = DbType.Decimal;
typeMap[typeof(bool?)] = DbType.Boolean;
typeMap[typeof(char?)] = DbType.StringFixedLength;
typeMap[typeof(Guid?)] = DbType.Guid;
typeMap[typeof(DateTime?)] = DbType.DateTime;
typeMap[typeof(DateTimeOffset?)] = DbType.DateTimeOffset;
typeMap[typeof(System.Data.Linq.Binary)] = DbType.Binary;

To get a relevant DbType, all you need to do is:要获得相关的 DbType,您需要做的就是:

var type = typeMap[typeof(string)]; // returns DbType.String

You can convert TypeCode to DbType using method ConvertTypeCodeToDbType in System.Web.UI.WebControls.Parameter class: Parameter.ConvertTypeCodeToDbType Method .您可以使用System.Web.UI.WebControls.Parameter类中的方法ConvertTypeCodeToDbTypeTypeCode转换为DbTypeParameter.ConvertTypeCodeToDbType Method To get TypeCode you can use method Type.GetTypeCode(Type type) .要获取TypeCode您可以使用方法Type.GetTypeCode(Type type)

You look at the documentation - SQL Server Data Type Mappings (ADO.NET) .你看看文档 - SQL Server Data Type Mappings (ADO.NET)

The mappings for other providers are also documented .记录了其他提供程序的映射。

These give you enough information to write a converter.这些为您提供了足够的信息来编写转换器。

I know it is old question which is already answered, but there is easier way by using SqlParameter , which already has this logic implemented.我知道这是一个已经回答的老问题,但是使用SqlParameter有更简单的方法,它已经实现了这个逻辑。 This is specific for SqlServer , but the providers for Postgre , MySql .. etc have corresponding implementations.这是特定于SqlServer 的,但PostgreMySql .. 等的提供者有相应的实现。

Here is a complete function which handles non-nullable, nullable primitive types , decimal and string这是一个处理不可为空、可为空的原始类型十进制字符串的完整函数

public static DbType GetDbType(Type runtimeType)
{
    var nonNullableType = Nullable.GetUnderlyingType(runtimeType);
    if (nonNullableType != null)
    {
        runtimeType = nonNullableType;
    }

    var templateValue = (Object)null;
    if (runtimeType.IsClass == false)
    {
        templateValue = Activator.CreateInstance(runtimeType);
    }

    var sqlParamter = new SqlParameter(parameterName: String.Empty, value: templateValue);

    return sqlParamter.DbType;
}

How to get SqlParameter:获取SqlParameter的方法:

For SqlServer , depending on your .netframework version you can find the SqlParamter type in System.Data , System.Data.SqlClient nuget and Microsoft.Data.SqlClient nuget对于SqlServer ,根据您的 .netframework 版本,您可以在System.DataSystem.Data.SqlClient nugetMicrosoft.Data.SqlClient nuget 中找到SqlParamter类型


Source code for SqlParameter: SqlParameter 的源代码:

The implementation of SqlParameter is using this piece of code which is pretty close to what the accepted answer is proposing. SqlParameter的实现正在使用这段代码,它与接受的答案所提出的非常接近。

I am not aware of any automated logic, you should do the mapping yourself because those are different types and the .NET Framework cannot do this for you alone.我不知道任何自动化逻辑,您应该自己进行映射,因为它们是不同的类型,而 .NET Framework 无法单独为您完成此操作。

see here the whole mapping table: SQL Server Data Type Mappings (ADO.NET) you can imagine that for Oracle, MySQL, sqLite and other engines there could be similar tables also depending on the .NET data provider / connect在这里看到整个映射表: SQL Server Data Type Mappings (ADO.NET)你可以想象对于 Oracle、MySQL、sqLite 和其他引擎,也可能有类似的表,这也取决于 .NET 数据提供者/连接

I'm leaving this here in case anyone else should happen to need the inverse of the Dapper lookup-table mentioned in alexn's answer.我把这个留在这里,以防其他人碰巧需要 alexn 的回答中提到的 Dapper 查找表的逆。 (it won't handle nullables) (它不会处理可空值)

Dictionary<DbType, Type> dbTypeMap = new Dictionary<DbType, Type>()
{
    { DbType.Binary, typeof(byte[])},
    { DbType.Boolean, typeof(bool)},
    { DbType.Byte, typeof(byte)},
    { DbType.DateTime, typeof(DateTime)},
    { DbType.DateTimeOffset, typeof(DateTimeOffset)},
    { DbType.Decimal, typeof(decimal)},
    { DbType.Double, typeof(double)},
    { DbType.Guid, typeof(Guid)},
    { DbType.Int16, typeof(short)},
    { DbType.Int32, typeof(int)},
    { DbType.Int64, typeof(long)},
    { DbType.SByte, typeof(sbyte)},
    { DbType.Single, typeof(float)},
    { DbType.String, typeof(string)},
    { DbType.StringFixedLength, typeof(char)},
    { DbType.UInt16, typeof(ushort)},
    { DbType.UInt32, typeof(uint)},
    { DbType.UInt64, typeof(ulong)}
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM