簡體   English   中英

如何將 System.Type 解析為 System.Data.DbType?

[英]How to resolve System.Type to 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

您可以使用System.Web.UI.WebControls.Parameter類中的方法ConvertTypeCodeToDbTypeTypeCode轉換為DbTypeParameter.ConvertTypeCodeToDbType Method 要獲取TypeCode您可以使用方法Type.GetTypeCode(Type type)

你看看文檔 - SQL Server Data Type Mappings (ADO.NET)

記錄了其他提供程序的映射。

這些為您提供了足夠的信息來編寫轉換器。

我知道這是一個已經回答的老問題,但是使用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.DataSystem.Data.SqlClient nugetMicrosoft.Data.SqlClient nuget 中找到SqlParamter類型


SqlParameter 的源代碼:

SqlParameter的實現正在使用這段代碼,它與接受的答案所提出的非常接近。

我不知道任何自動化邏輯,您應該自己進行映射,因為它們是不同的類型,而 .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)}
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM