Anybody got a C# function that maps the SQL datatype of a column to its CLR equivalent?

后端 未结 12 1700
逝去的感伤
逝去的感伤 2020-12-12 16:18

I\'m sitting down to write a massive switch() statement to turn SQL datatypes into CLR datatypes in order to generate classes from MSSQL stored procedures. I\'m using this c

相关标签:
12条回答
  • 2020-12-12 16:46

    This is the one we use. You may want to tweak it (e.g. nullable/non-nullable types etc.) but it should save you most of the typing.

    public static Type GetClrType(SqlDbType sqlType)
    {
        switch (sqlType)
        {
            case SqlDbType.BigInt:
                return typeof(long?);
    
            case SqlDbType.Binary:
            case SqlDbType.Image:
            case SqlDbType.Timestamp:
            case SqlDbType.VarBinary:
                return typeof(byte[]);
    
            case SqlDbType.Bit:
                return typeof(bool?);
    
            case SqlDbType.Char:
            case SqlDbType.NChar:
            case SqlDbType.NText:
            case SqlDbType.NVarChar:
            case SqlDbType.Text:
            case SqlDbType.VarChar:
            case SqlDbType.Xml:
                return typeof(string);
    
            case SqlDbType.DateTime:
            case SqlDbType.SmallDateTime:
            case SqlDbType.Date:
            case SqlDbType.Time:
            case SqlDbType.DateTime2:
                return typeof(DateTime?);
    
            case SqlDbType.Decimal:
            case SqlDbType.Money:
            case SqlDbType.SmallMoney:
                return typeof(decimal?);
    
            case SqlDbType.Float:
                return typeof(double?);
    
            case SqlDbType.Int:
                return typeof(int?);
    
            case SqlDbType.Real:
                return typeof(float?);
    
            case SqlDbType.UniqueIdentifier:
                return typeof(Guid?);
    
            case SqlDbType.SmallInt:
                return typeof(short?);
    
            case SqlDbType.TinyInt:
                return typeof(byte?);
    
            case SqlDbType.Variant:
            case SqlDbType.Udt:
                return typeof(object);
    
            case SqlDbType.Structured:
                return typeof(DataTable);
    
            case SqlDbType.DateTimeOffset:
                return typeof(DateTimeOffset?);
    
            default:
                throw new ArgumentOutOfRangeException("sqlType");
        }
    }
    
    0 讨论(0)
  • 2020-12-12 16:49

    I think there is no built in for that, but you can use VS to generate classes for your tables and then try to edit them

    0 讨论(0)
  • 2020-12-12 16:52

    I include this extension (you could easily exchange the string key in the dictionary for SqlDbType as Greg has implemented - or even support both) in my model and expose a property that converts the CLR Type:

        namespace X.Domain.Model
        {
            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            public class StoredProcedureParameter : DomainObject
            {
                public StoredProcedureParameter() { }
    
                public string StoredProcedure { get; set; }
    
                public string ProcedureSchema { get; set; }
    
                public string ProcedureName { get; set; }
    
                public string ParameterName { get; set; }
    
                public string ParameterOrder { get; set; }
    
                public string ParameterMode { get; set; }
    
                public string SqlDataType { get; set; }
    
                public Type DataType { get { return this.SqlDataType.ToClrType(); } }
            }
    
            static class StoredProcedureParameterExtensions
            {
                private static Dictionary<string, Type> Mappings;
                public static StoredProcedureParameterExtensions()
                {
                    Mappings = new Dictionary<string, Type>();
                    Mappings.Add("bigint", typeof(Int64));
                    Mappings.Add("binary", typeof(Byte[]));
                    Mappings.Add("bit", typeof(Boolean));
                    Mappings.Add("char", typeof(String));
                    Mappings.Add("date", typeof(DateTime));
                    Mappings.Add("datetime", typeof(DateTime));
                    Mappings.Add("datetime2", typeof(DateTime));
                    Mappings.Add("datetimeoffset", typeof(DateTimeOffset));
                    Mappings.Add("decimal", typeof(Decimal));
                    Mappings.Add("float", typeof(Double));
                    Mappings.Add("image", typeof(Byte[]));
                    Mappings.Add("int", typeof(Int32));
                    Mappings.Add("money", typeof(Decimal));
                    Mappings.Add("nchar", typeof(String));
                    Mappings.Add("ntext", typeof(String));
                    Mappings.Add("numeric", typeof(Decimal));
                    Mappings.Add("nvarchar", typeof(String));
                    Mappings.Add("real", typeof(Single));
                    Mappings.Add("rowversion", typeof(Byte[]));
                    Mappings.Add("smalldatetime", typeof(DateTime));
                    Mappings.Add("smallint", typeof(Int16));
                    Mappings.Add("smallmoney", typeof(Decimal));
                    Mappings.Add("text", typeof(String));
                    Mappings.Add("time", typeof(TimeSpan));
                    Mappings.Add("timestamp", typeof(Byte[]));
                    Mappings.Add("tinyint", typeof(Byte));
                    Mappings.Add("uniqueidentifier", typeof(Guid));
                    Mappings.Add("varbinary", typeof(Byte[]));
                    Mappings.Add("varchar", typeof(String));
    
                }
    
                public static Type ToClrType(this string sqlType)
                {
                    Type datatype = null;
                    if (Mappings.TryGetValue(sqlType, out datatype))
                        return datatype;
                    throw new TypeLoadException(string.Format("Can not load CLR Type from {0}", sqlType));
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-12 16:52

    You can try Wizardby. However, it maps from so-called "native" data types to DbType, which are then trivial to convert to CLR types. If this fits, you'll need an appropriate IDbTypeMapper - either SqlServer2000TypeMapper or SqlServer2005TypeMapper.

    0 讨论(0)
  • 2020-12-12 16:57

    You don't need a function.I think you may be looking for

    dt.Columns[i].DataType.UnderlyingSystemType
    

    dt - dataTable

    This will return the CLR type for corresponding column. Hope this helps and BTW this is my first answer on stack overflow

    0 讨论(0)
  • 2020-12-12 17:00

    Why not create a typed dataset and have the VS designer do the mapping for you? Unless the project has to adapt at runtime to different schemas, then you should use code generation techniques to create your classes, wether the built-in designers (ie. typed datasets) or custom ones (schema->XML->XSLT->.cs).

    0 讨论(0)
提交回复
热议问题