【发布时间】:2021-10-14 01:23:41
【问题描述】:
在 System 命名空间中查找基类库类型的 System.Data.DbType 枚举值的最佳方法是什么?
【问题讨论】:
在 System 命名空间中查找基类库类型的 System.Data.DbType 枚举值的最佳方法是什么?
【问题讨论】:
一种常见的方法是使用类型映射,显式映射所有支持的类型(不同的连接器/提供者支持不同的类型)。这是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;
要获得相关的 DbType,您只需:
var type = typeMap[typeof(string)]; // returns DbType.String
【讨论】:
Type.GetGenericTypeDefinition 和 Type.GetGenericArguments 将有助于解决 Nullable 值和基础类型。
您可以使用System.Web.UI.WebControls.Parameter 类中的ConvertTypeCodeToDbType 方法将TypeCode 转换为DbType:Parameter.ConvertTypeCodeToDbType Method。
要获取TypeCode,您可以使用方法Type.GetTypeCode(Type type)。
【讨论】:
System.Web?
【讨论】:
DbType 尽可能代表所有数据库。
我知道这是一个已经回答的老问题,但是使用SqlParameter 有更简单的方法,它已经实现了这个逻辑。
这是 SqlServer 特有的,但 Postgre、MySql .. 等的提供程序都有相应的实现。
这是一个完整的函数,它处理不可为空、可空的原始类型、十进制和字符串
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、System.Data.SqlClient nuget 中找到 SqlParamter 类型strong> 和 Microsoft.Data.SqlClient nuget
SqlParameter源代码:
SqlParameter 的实现使用了this piece of code,这与公认答案的提议非常接近。
【讨论】:
我不知道有任何自动化逻辑,您应该自己进行映射,因为它们是不同的类型,而 .NET Framework 无法单独为您完成。
在此处查看整个映射表:SQL Server Data Type Mappings (ADO.NET) 您可以想象对于 Oracle、MySQL、sqlite 和其他引擎,也可能有类似的表,也取决于 .NET 数据提供程序/连接
【讨论】:
我把这个留在这里,以防其他人碰巧需要 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)}
};
【讨论】: