首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET系统类型到SqlDbType

.NET系统类型到SqlDbType
EN

Stack Overflow用户
提问于 2016-03-02 10:57:12
回答 4查看 25.8K关注 0票数 19

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

代码语言:javascript
复制
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的有用函数。

代码语言:javascript
复制
   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)];
     }

有没有人知道如何以更清洁、更好、更好的方式获得同样的结果?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-03-02 11:02:21

您的方法是一个很好的开端,但正如Ian在一条评论中所说的那样,填充字典应该只做一次。

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

警告

下面是一个有用的例子,但是您需要注意,这种方法确实存在一些问题。例如:

  • 对于string,如何在CharNCharVarCharNVarCharTextNText (甚至可能是Xml__ )之间选择正确的
  • 对于像byte[]这样的blobs,您应该使用BinaryVarBinary还是Image
  • 对于decimalfloatdouble,你应该选择DecimalFloatMoneySmallMoney还是Real
  • 对于DateTime,您需要DateTime2DateTimeOffsetDateTime还是SmallDateTime
  • 您是否使用Nullable类型,如int??这很可能会给出与底层类型相同的SqlDbType

另外,仅仅提供一个Type就不会告诉您其他约束,比如字段大小和精度。做出正确的决定还涉及如何在应用程序中使用数据以及如何将数据存储在数据库中。

最好的做法就是让奥姆为您做这件事。

代码语言:javascript
复制
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));
    }
}

这就是你使用它的方法:

代码语言:javascript
复制
var sqlDbType = SqlHelper.GetDbType<string>();
// or:
var sqlDbType = SqlHelper.GetDbType(typeof(DateTime?));
// or:
var sqlDbType = SqlHelper.GetDbType(property.PropertyType);
票数 21
EN

Stack Overflow用户

发布于 2017-12-12 18:54:11

这类查找表似乎已经可用,尽管不是在System.Data (或.Object.Type)中,而是在System.Web中。

项目->添加引用-> System.Web -> OK

然后https://msdn.microsoft.com/en-us/library/system.data.sqldbtype(v=vs.110).aspx还说

在设置命令参数时,将链接SqlDbType和DbType。因此,设置DbType将SqlDbType更改为支持的SqlDbType。

因此,这在理论上应该可行;)

代码语言:javascript
复制
using Microsoft.SqlServer.Server; // SqlDataRecord and SqlMetaData
using System;
using System.Collections; // IEnumerator and IEnumerable
using System.Collections.Generic; // general IEnumerable and IEnumerator
using System.Data; // DataTable and SqlDataType
using System.Data.SqlClient; // SqlConnection, SqlCommand, and SqlParameter
using System.Web.UI.WebControls; // for Parameters.Convert... functions

private static SqlDbType TypeToSqlDbType(Type t) {
    DbType dbtc = Parameters.ConvertTypeCodeToDbType(t.GetTypeCodeImpl());
    SqlParameter sp = new SqlParameter();
    // DbParameter dp = new DbParameter();
    // dp.DbType = dbtc;
    sp.DbType = dbtc;
    return sp.SqlDbType;
}
票数 11
EN

Stack Overflow用户

发布于 2019-03-11 23:34:08

我的同事给了我一个主意,让我尝试一下SqlParameter的一个属性:

代码语言:javascript
复制
Func<Object, SqlDbType> getSqlType = val => new SqlParameter("Test", val).SqlDbType;
Func<Type, SqlDbType> getSqlType2 = type => new SqlParameter("Test", type.IsValueType?Activator.CreateInstance(type):null).SqlDbType;

//returns nvarchar...
Object obj = "valueToTest";
getSqlType(obj).Dump();
getSqlType2(typeof(String)).Dump();

//returns int...
obj = 4;
getSqlType(obj).Dump();
getSqlType2(typeof(Int32)).Dump();

//returns bigint...
obj = Int64.MaxValue;
getSqlType(obj).Dump();
getSqlType2(typeof(Int64)).Dump();

https://dotnetfiddle.net/8heM4H

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35745226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档