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

发布于 2024-12-13 01:09:20 字数 163 浏览 1 评论 0原文

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

What is the best way to find System.Data.DbType enumeration value for Base Class Library types in System namespace?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

对你的占有欲 2024-12-20 01:09:21

我知道这是一个已经回答的老问题,但是使用 SqlParameter 有更简单的方法,它已经实现了这个逻辑。
这是特定于SqlServer的,但是PostgreMySql等的提供者都有相应的实现。

这是一个完整的函数,它处理不可为空、可为空的基本类型小数字符串

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

如何获取SqlParameter:

对于SqlServer,根据您的.netframework版本,您可以在System.Data中找到SqlParamter类型, System.Data.SqlClient nugetMicrosoft.Data.SqlClient nuget


SqlParameter 的源代码:

<一个href="https://github.com/dotnet/SqlClient/blob/d6f2e29cda769e711988c64d3cb57eb5010a3e9c/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlParameter.cs#L341" rel="noreferrer">SqlParameter 正在使用 此一段代码是非常接近已接受的答案所提议的内容。

I know it is old question which is already answered, but there is easier way by using SqlParameter, which already has this logic implemented.
This is specific for SqlServer, but the providers for Postgre, MySql .. etc have corresponding implementations.

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:

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


Source code for SqlParameter:

The implementation of SqlParameter is using this piece of code which is pretty close to what the accepted answer is proposing.

合久必婚 2024-12-20 01:09:21

我不知道任何自动化逻辑,您应该自己进行映射,因为这些是不同的类型,.NET Framework 无法单独为您完成此操作。

请参阅此处的整个映射表:SQL Server 数据类型映射 (ADO.NET) 你可以想象,对于 Oracle、MySQL、sqlite 和其他引擎,也可能有类似的表,具体取决于 .NET 数据提供程序/连接

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.

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

眼泪也成诗 2024-12-20 01:09:21

我将其留在这里,以防其他人碰巧需要 alexn 的答案中提到的 Dapper 查找表的逆。 (它不会处理可空值)

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

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. (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)}
};
渡你暖光 2024-12-20 01:09:20

一种常见的方法是使用类型映射,显式映射所有支持的类型(不同的连接器/提供程序支持不同的类型)。 的类型映射:

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;

以下是 Dapper 相关的DbType,您需要做的就是:

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

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:

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:

var type = typeMap[typeof(string)]; // returns DbType.String
身边 2024-12-20 01:09:20

您可以使用 System.Web.UI.WebControls.Parameter 类中的 ConvertTypeCodeToDbType 方法将 TypeCode 转换为 DbType: a href="https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.parameter.converttypecodetodbtype(v=vs.110).aspx" rel="noreferrer">Parameter.ConvertTypeCodeToDbType 方法。
要获取 TypeCode,您可以使用方法 Type.GetTypeCode(Type type)

You can convert TypeCode to DbType using method ConvertTypeCodeToDbType in System.Web.UI.WebControls.Parameter class: Parameter.ConvertTypeCodeToDbType Method.
To get TypeCode you can use method Type.GetTypeCode(Type type).

梦里的微风 2024-12-20 01:09:20

您查看文档 - SQL Server 数据类型映射 (ADO.NET)

其他提供商的映射也已记录

这些为您提供了编写转换器的足够信息。

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

The mappings for other providers are also documented.

These give you enough information to write a converter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文