gpt4 book ai didi

c# - .NET 系统类型到 SqlDbType

转载 作者:可可西里 更新时间:2023-11-01 07:55:00 26 4
gpt4 key购买 nike

我一直在寻找 .Net System.Type 和 SqlDbType 之间的智能转换。我发现它是以下想法:

private static SqlDbType TypeToSqlDbType(Type t)
{
String name = t.Name;
SqlDbType val = SqlDbType.VarChar; // default value
try
{
if (name.Contains("16") || name.Contains("32") || name.Contains("64"))
{
name = name.Substring(0, name.Length - 2);
}
val = (SqlDbType)Enum.Parse(typeof(SqlDbType), name, true);
}
catch (Exception)
{
// add error handling to suit your taste
}

return val;
}

上面的代码不是很好,有代码味,这就是为什么我写了下面的代码,幼稚,不聪明,但有用的功能,基于https://msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx :

   public static SqlDbType ConvertiTipo(Type giveType)
{
var typeMap = new Dictionary<Type, SqlDbType>();

typeMap[typeof(string)] = SqlDbType.NVarChar;
typeMap[typeof(char[])] = SqlDbType.NVarChar;
typeMap[typeof(int)] = SqlDbType.Int;
typeMap[typeof(Int32)] = SqlDbType.Int;
typeMap[typeof(Int16)] = SqlDbType.SmallInt;
typeMap[typeof(Int64)] = SqlDbType.BigInt;
typeMap[typeof(Byte[])] = SqlDbType.VarBinary;
typeMap[typeof(Boolean)] = SqlDbType.Bit;
typeMap[typeof(DateTime)] = SqlDbType.DateTime2;
typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
typeMap[typeof(Decimal)] = SqlDbType.Decimal;
typeMap[typeof(Double)] = SqlDbType.Float;
typeMap[typeof(Decimal)] = SqlDbType.Money;
typeMap[typeof(Byte)] = SqlDbType.TinyInt;
typeMap[typeof(TimeSpan)] = SqlDbType.Time;

return typeMap[(giveType)];
}

有人知道如何以更干净、更好、更好的方式获得相同的结果吗?

最佳答案

您的方法是一个好的开始,但正如 Ian 在评论中所说,填充该字典应该只完成一次

这里有一个基于相同想法的 GIST,尽管它不会在相同类型集之间进行转换:https://gist.github.com/abrahamjp/858392

警告

我有a working example下面,但您需要注意这种方法确实存在一些问题。例如:

  • 对于string,如何在CharNCharVarCharNVarCharTextNText (甚至可能是 Xml)
  • 对于像 byte[] 这样的 blob,您应该使用 BinaryVarBinary 还是 Image
  • 对于decimalfloatdouble,你应该选择DecimalFloat code>、MoneySmallMoney 还是 Real
  • 对于 DateTime,您需要 DateTime2DateTimeOffsetDateTime 还是 SmallDateTime?
  • 您是否使用 Nullable 类型,例如 int??这些很可能会提供与基础类型相同的 SqlDbType

此外,仅提供 Type 不会告诉您其他约束,例如字段大小和精度。做出正确的决定还与数据在您的应用程序中的使用方式以及数据在数据库中的存储方式有关。

最好的办法就是让ORM为你做这个。

代码

public static class SqlHelper
{
private static Dictionary<Type, SqlDbType> typeMap;

// Create and populate the dictionary in the static constructor
static SqlHelper()
{
typeMap = new Dictionary<Type, SqlDbType>();

typeMap[typeof(string)] = SqlDbType.NVarChar;
typeMap[typeof(char[])] = SqlDbType.NVarChar;
typeMap[typeof(byte)] = SqlDbType.TinyInt;
typeMap[typeof(short)] = SqlDbType.SmallInt;
typeMap[typeof(int)] = SqlDbType.Int;
typeMap[typeof(long)] = SqlDbType.BigInt;
typeMap[typeof(byte[])] = SqlDbType.Image;
typeMap[typeof(bool)] = SqlDbType.Bit;
typeMap[typeof(DateTime)] = SqlDbType.DateTime2;
typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
typeMap[typeof(decimal)] = SqlDbType.Money;
typeMap[typeof(float)] = SqlDbType.Real;
typeMap[typeof(double)] = SqlDbType.Float;
typeMap[typeof(TimeSpan)] = SqlDbType.Time;
/* ... and so on ... */
}

// Non-generic argument-based method
public static SqlDbType GetDbType(Type giveType)
{
// Allow nullable types to be handled
giveType = Nullable.GetUnderlyingType(giveType) ?? giveType;

if (typeMap.ContainsKey(giveType))
{
return typeMap[giveType];
}

throw new ArgumentException($"{giveType.FullName} is not a supported .NET class");
}

// Generic version
public static SqlDbType GetDbType<T>()
{
return GetDbType(typeof(T));
}
}

这就是您将如何使用它:

var sqlDbType = SqlHelper.GetDbType<string>();
// or:
var sqlDbType = SqlHelper.GetDbType(typeof(DateTime?));
// or:
var sqlDbType = SqlHelper.GetDbType(property.PropertyType);

关于c# - .NET 系统类型到 SqlDbType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35745226/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com