48

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 chart as a reference. Before I get too far into what will probably take all day and be a huge pain to fully test, I'd like to call out to the SO community to see if anyone else has already written or found something in C# to accomplish this seemingly common and assuredly tedious task.

Chris McCall
  • 10,317
  • 8
  • 49
  • 80
  • I have in the past implemented a very similar system, but not for C#. I've been meaning to build something like this, but I just haven't got around to it yet. Is your implementation going to be closed or might it be open-sourced? Because I'm sure I and others would be very interested in an open source implementation of just what you describe. – Daniel Pryden Aug 31 '09 at 17:26
  • This is for commercial development. – Chris McCall Aug 31 '09 at 18:41
  • This may not have been available in 2009, but System.Web may have what is required here: https://stackoverflow.com/a/28561947/4228193 . `try { return Convert.ChangeType(value_to_convert, Parameter.ConvertDbTypeToTypeCode(SqlMetaData_instance.DbT‌​ype); }` also available: ConvertTypeCodeToDbType (https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.parameter.converttypecodetodbtype(v=vs.110).aspx) – mpag Dec 12 '17 at 18:00

13 Answers13

75

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");
    }
}
Gabriel Nahmias
  • 920
  • 3
  • 15
  • 20
Greg Beech
  • 133,383
  • 43
  • 204
  • 250
  • How do you make use of this method? – crdx Oct 11 '11 at 15:08
  • 9
    @user457104 - Erm... you call it like any other method. – Greg Beech Oct 12 '11 at 10:09
  • 1
    No, I mean, I don't understand what you use it for. Do you use the return value to dynamically create the type? Do you use it to compare it to something else? In code, in what situation would I want to convert from SqlDbType to Type? I'm sure there's a good use for it, but I can't think of it. Hence, I'm asking. – crdx Oct 13 '11 at 11:29
  • 1
    @user457104 - We use it in our tool that generates .NET wrapper classes for our stored procedures. It determines the SQL parameter types and generates a wrapper with the corresponding CLR type using this function. It's not that common a use case really. – Greg Beech Oct 13 '11 at 15:14
  • Where is HierarchyId ? – FrenkyB Mar 18 '15 at 08:09
  • I get an error: "Static types cannot be used as parameters". – Dave May 28 '15 at 21:18
  • Why returning nullable CLR types ? – activebiz Jul 03 '15 at 13:20
  • @activebiz nullable columns... You could test for column nullability as well if you wanted to really jazz it up... – Chris McCall Jun 30 '16 at 14:02
9
    /****** Object:  Table [dbo].[DbVsCSharpTypes]    Script Date: 03/20/2010 03:07:56 ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DbVsCSharpTypes]') 
    AND type in (N'U'))
    DROP TABLE [dbo].[DbVsCSharpTypes]
    GO

    /****** Object:  Table [dbo].[DbVsCSharpTypes]    Script Date: 03/20/2010 03:07:56 ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[DbVsCSharpTypes](
        [DbVsCSharpTypesId] [int] IDENTITY(1,1) NOT NULL,
        [Sql2008DataType] [varchar](200) NULL,
        [CSharpDataType] [varchar](200) NULL,
        [CLRDataType] [varchar](200) NULL,
        [CLRDataTypeSqlServer] [varchar](2000) NULL,

     CONSTRAINT [PK_DbVsCSharpTypes] PRIMARY KEY CLUSTERED 
    (
        [DbVsCSharpTypesId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO


    SET NOCOUNT ON;
    SET XACT_ABORT ON;
    GO

    SET IDENTITY_INSERT [dbo].[DbVsCSharpTypes] ON;
    BEGIN TRANSACTION;
    INSERT INTO [dbo].[DbVsCSharpTypes]([DbVsCSharpTypesId], [Sql2008DataType], [CSharpDataType], [CLRDataType], [CLRDataTypeSqlServer])
    SELECT 1, N'bigint', N'long', N'Int64, Nullable<Int64>', N'SqlInt64' UNION ALL
    SELECT 2, N'binary', N'byte[]', N'Byte[]', N'SqlBytes, SqlBinary' UNION ALL
    SELECT 3, N'bit', N'bool', N'Boolean, Nullable<Boolean>', N'SqlBoolean' UNION ALL
    SELECT 4, N'char', N'char', NULL, NULL UNION ALL
    SELECT 5, N'cursor', NULL, NULL, NULL UNION ALL
    SELECT 6, N'date', N'DateTime', N'DateTime, Nullable<DateTime>', N'SqlDateTime' UNION ALL
    SELECT 7, N'datetime', N'DateTime', N'DateTime, Nullable<DateTime>', N'SqlDateTime' UNION ALL
    SELECT 8, N'datetime2', N'DateTime', N'DateTime, Nullable<DateTime>', N'SqlDateTime' UNION ALL
    SELECT 9, N'DATETIMEOFFSET', N'DateTimeOffset', N'DateTimeOffset', N'DateTimeOffset, Nullable<DateTimeOffset>' UNION ALL
    SELECT 10, N'decimal', N'decimal', N'Decimal, Nullable<Decimal>', N'SqlDecimal' UNION ALL
    SELECT 11, N'float', N'double', N'Double, Nullable<Double>', N'SqlDouble' UNION ALL
    SELECT 12, N'geography', NULL, NULL, N'SqlGeography is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.' UNION ALL
    SELECT 13, N'geometry', NULL, NULL, N'SqlGeometry is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.' UNION ALL
    SELECT 14, N'hierarchyid', NULL, NULL, N'SqlHierarchyId is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.' UNION ALL
    SELECT 15, N'image', NULL, NULL, NULL UNION ALL
    SELECT 16, N'int', N'int', N'Int32, Nullable<Int32>', N'SqlInt32' UNION ALL
    SELECT 17, N'money', N'decimal', N'Decimal, Nullable<Decimal>', N'SqlMoney' UNION ALL
    SELECT 18, N'nchar', N'string', N'String, Char[]', N'SqlChars, SqlString' UNION ALL
    SELECT 19, N'ntext', NULL, NULL, NULL UNION ALL
    SELECT 20, N'numeric', N'decimal', N'Decimal, Nullable<Decimal>', N'SqlDecimal' UNION ALL
    SELECT 21, N'nvarchar', N'string', N'String, Char[]', N'SqlChars, SqlStrinG SQLChars is a better match for data transfer and access, and SQLString is a better match for performing String operations.' UNION ALL
    SELECT 22, N'nvarchar(1), nchar(1)', N'string', N'Char, String, Char[], Nullable<char>', N'SqlChars, SqlString' UNION ALL
    SELECT 23, N'real', N'single', N'Single, Nullable<Single>', N'SqlSingle' UNION ALL
    SELECT 24, N'rowversion', N'byte[]', N'Byte[]', NULL UNION ALL
    SELECT 25, N'smallint', N'smallint', N'Int16, Nullable<Int16>', N'SqlInt16' UNION ALL
    SELECT 26, N'smallmoney', N'decimal', N'Decimal, Nullable<Decimal>', N'SqlMoney' UNION ALL
    SELECT 27, N'sql_variant', N'object', N'Object', NULL UNION ALL
    SELECT 28, N'table', NULL, NULL, NULL UNION ALL
    SELECT 29, N'text', N'string', NULL, NULL UNION ALL
    SELECT 30, N'time', N'TimeSpan', N'TimeSpan, Nullable<TimeSpan>', N'TimeSpan' UNION ALL
    SELECT 31, N'timestamp', NULL, NULL, NULL UNION ALL
    SELECT 32, N'tinyint', N'byte', N'Byte, Nullable<Byte>', N'SqlByte' UNION ALL
    SELECT 33, N'uniqueidentifier', N'Guid', N'Guid, Nullable<Guid>', N'SqlGuidUser-defined type(UDT)The same class that is bound to the user-defined type in the same assembly or a dependent assembly.' UNION ALL
    SELECT 34, N'varbinary ', N'byte[]', N'Byte[]', N'SqlBytes, SqlBinary' UNION ALL
    SELECT 35, N'varbinary(1), binary(1)', N'byte', N'byte, Byte[], Nullable<byte>', N'SqlBytes, SqlBinary' UNION ALL
    SELECT 36, N'varchar', NULL, NULL, NULL UNION ALL
    SELECT 37, N'xml', NULL, NULL, N'SqlXml'
    COMMIT;
    RAISERROR (N'[dbo].[DbVsCSharpTypes]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT;
    GO

    SET IDENTITY_INSERT [dbo].[DbVsCSharpTypes] OFF;
Yordan Georgiev
  • 5,114
  • 1
  • 56
  • 53
  • 5
    The only way to handle data is to be able to handle the metadata. In order to be able to handle the metadata one should be able use its data. In order to be able to use its data it must be described properly ... – Yordan Georgiev Jun 07 '11 at 23:26
  • I can't believe no one has spotted this in the last 4.5 years, but a SQL bigint isn't equivalent to a C# short.. I think you meant long (aka Int64)! – ubercam Oct 29 '14 at 10:11
  • 1
    Is there a reason varchar has NULL data types? – tbone Jun 01 '15 at 22:41
  • Good point. The only reason I could think of is just the fact that the code was in "work in progress status" - that is without testing now I changed it to NOT NULL by intuition ... unless anyone justifies why it should not be done ... – Yordan Georgiev Jun 02 '15 at 09:01
  • Good table but one column is missing MSSQL system_type_id – user1325696 Sep 09 '15 at 08:24
6

Here's a revision that accepts nullable.

    public static Type GetClrType(SqlDbType sqlType, bool isNullable)
    {
        switch (sqlType)
        {
            case SqlDbType.BigInt:
                return isNullable ? typeof(long?) : typeof(long);

            case SqlDbType.Binary:
            case SqlDbType.Image:
            case SqlDbType.Timestamp:
            case SqlDbType.VarBinary:
                return typeof(byte[]);

            case SqlDbType.Bit:
                return isNullable ? typeof(bool?) : 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 isNullable ? typeof(DateTime?) : typeof(DateTime);

            case SqlDbType.Decimal:
            case SqlDbType.Money:
            case SqlDbType.SmallMoney:
                return isNullable ? typeof(decimal?) : typeof(decimal);

            case SqlDbType.Float:
                return isNullable ? typeof(double?) : typeof(double);

            case SqlDbType.Int:
                return isNullable ? typeof(int?) : typeof(int);

            case SqlDbType.Real:
                return isNullable ? typeof(float?) : typeof(float);

            case SqlDbType.UniqueIdentifier:
                return isNullable ? typeof(Guid?) : typeof(Guid);

            case SqlDbType.SmallInt:
                return isNullable ? typeof(short?) : typeof(short);

            case SqlDbType.TinyInt:
                return isNullable ? typeof(byte?) : typeof(byte);

            case SqlDbType.Variant:
            case SqlDbType.Udt:
                return typeof(object);

            case SqlDbType.Structured:
                return typeof(DataTable);

            case SqlDbType.DateTimeOffset:
                return isNullable ? typeof(DateTimeOffset?) : typeof(DateTimeOffset);

            default:
                throw new ArgumentOutOfRangeException("sqlType");
        }
    }
Tom
  • 101
  • 1
  • 2
5
    internal Type type(SqlDbType sqltype)
    {
        Type resulttype = null;
        Dictionary<SqlDbType, Type> Types = new Dictionary<SqlDbType, Type>();
        Types.Add(SqlDbType.BigInt, typeof(Int64));
        Types.Add(SqlDbType.Binary, typeof(Byte[]));
        Types.Add(SqlDbType.Bit, typeof(Boolean));
        Types.Add(SqlDbType.Char, typeof(String));
        Types.Add(SqlDbType.Date, typeof(DateTime));
        Types.Add(SqlDbType.DateTime, typeof(DateTime));
        Types.Add(SqlDbType.DateTime2, typeof(DateTime));
        Types.Add(SqlDbType.DateTimeOffset, typeof(DateTimeOffset));
        Types.Add(SqlDbType.Decimal, typeof(Decimal));
        Types.Add(SqlDbType.Float, typeof(Double));
        Types.Add(SqlDbType.Image, typeof(Byte[]));
        Types.Add(SqlDbType.Int, typeof(Int32));
        Types.Add(SqlDbType.Money, typeof(Decimal));
        Types.Add(SqlDbType.NChar, typeof(String));
        Types.Add(SqlDbType.NText, typeof(String));
        Types.Add(SqlDbType.NVarChar, typeof(String));
        Types.Add(SqlDbType.Real, typeof(Single));
        Types.Add(SqlDbType.SmallDateTime, typeof(DateTime));
        Types.Add(SqlDbType.SmallInt, typeof(Int16));
        Types.Add(SqlDbType.SmallMoney, typeof(Decimal));
        Types.Add(SqlDbType.Text, typeof(String));
        Types.Add(SqlDbType.Time, typeof(TimeSpan));
        Types.Add(SqlDbType.Timestamp, typeof(Byte[]));
        Types.Add(SqlDbType.TinyInt, typeof(Byte));
        Types.Add(SqlDbType.UniqueIdentifier, typeof(Guid));
        Types.Add(SqlDbType.VarBinary, typeof(Byte[]));
        Types.Add(SqlDbType.VarChar, typeof(String));
        Types.TryGetValue(sqltype, out resulttype);
        return resulttype;
    }

    internal SqlDbType type(Type systype)
    {
        SqlDbType resulttype = SqlDbType.NVarChar;
        Dictionary<Type, SqlDbType> Types = new Dictionary<Type, SqlDbType>();
        Types.Add(typeof(Boolean), SqlDbType.Bit);
        Types.Add(typeof(String), SqlDbType.NVarChar);
        Types.Add(typeof(DateTime), SqlDbType.DateTime);
        Types.Add(typeof(Int16), SqlDbType.Int);
        Types.Add(typeof(Int32), SqlDbType.Int);
        Types.Add(typeof(Int64), SqlDbType.Int);
        Types.Add(typeof(Decimal), SqlDbType.Float);
        Types.Add(typeof(Double), SqlDbType.Float);
        Types.TryGetValue(systype, out resulttype);
        return resulttype;
    }
Tarik H.
  • 51
  • 1
  • 1
  • Does anyone know if the `Dictionary.TryGetValue()` this approach shown here is any faster or slower than the `switch...case` appoach shown elsewhere in this thread? – Dib Oct 23 '15 at 06:11
5

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

ALLSYED
  • 1,523
  • 17
  • 15
3

This doesn't directly answer the question as asked, but it does answer a common related one. Once you have an IDataReader you can call IDataRecord.GetFieldType(int) to "[get] the Type information corresponding to the type of Object that would be returned from GetValue."

Doug McClean
  • 14,265
  • 6
  • 48
  • 70
  • 2
    If you've got an object that was read from a field, you can also use the SqlMetaData.InferFromValue (http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqlmetadata.inferfromvalue.aspx)method to work out it's type. – adrianbanks Jun 29 '09 at 14:33
3

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));
            }
        }
    }
jared.g
  • 408
  • 3
  • 6
2

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.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
2
using System.Data;
namespace System.CoreEssentials
{
    public static class SqlTypesExtensions
    {

        public static Type SqlToType(this string pSqlType)
        {
            switch (pSqlType)
            {
                case "bigint":
                case "real":
                    return typeof(long);
                case "numeric":
                    return typeof(decimal);
                case "bit":
                    return typeof(bool);

                case "smallint":
                    return typeof(short);

                case "decimal":
                case "smallmoney":
                case "money":
                    return typeof(decimal);

                case "int":
                    return typeof(int);

                case "tinyint":
                    return typeof(byte);

                case "float":
                    return typeof(float);

                case "date":
                case "datetime2":
                case "smalldatetime":
                case "datetime":
                case "time":
                    return typeof(DateTime);

                case "datetimeoffset":
                    return typeof(DateTimeOffset);

                case "char":
                case "varchar":
                case "text":
                case "nchar":
                case "nvarchar":
                case "ntext":
                    return typeof(string);


                case "binary":
                case "varbinary":
                case "image":
                    return typeof(byte[]);

                case "uniqueidentifier":
                    return typeof(Guid);

                default:
                    return typeof(string);

            }

        }

        public static DbType ToDbType(this Type pType)
        {
            switch (pType.Name.ToLower())
            {
                case "byte":
                    return DbType.Byte;
                case "sbyte":
                    return DbType.SByte;
                case "short":
                case "int16":
                    return DbType.Int16;
                case "uint16":
                    return DbType.UInt16;
                case "int32":
                    return DbType.Int32;
                case "uint32":
                    return DbType.UInt32;
                case "int64":
                    return DbType.Int64;
                case "uint64":
                    return DbType.UInt64;
                case "single":
                    return DbType.Single;
                case "double":
                    return DbType.Double;
                case "decimal":
                    return DbType.Decimal;
                case "bool":
                case "boolean":
                    return DbType.Boolean;
                case "string":
                    return DbType.String;
                case "char":
                    return DbType.StringFixedLength;
                case "Guid":
                    return DbType.Guid;
                case "DateTime":
                    return DbType.DateTime;
                case "DateTimeOffset":
                    return DbType.DateTimeOffset;
                case "byte[]":
                    return DbType.Binary;
                case "byte?":
                    return DbType.Byte;
                case "sbyte?":
                    return DbType.SByte;
                case "short?":
                    return DbType.Int16;
                case "ushort?":
                    return DbType.UInt16;
                case "int?":
                    return DbType.Int32;
                case "uint?":
                    return DbType.UInt32;
                case "long?":
                    return DbType.Int64;
                case "ulong?":
                    return DbType.UInt64;
                case "float?":
                    return DbType.Single;
                case "double?":
                    return DbType.Double;
                case "decimal?":
                    return DbType.Decimal;
                case "bool?":
                    return DbType.Boolean;
                case "char?":
                    return DbType.StringFixedLength;
                case "Guid?":
                    return DbType.Guid;
                case "DateTime?":
                    return DbType.DateTime;
                case "DateTimeOffset?":
                    return DbType.DateTimeOffset;
                default:
                    return DbType.String;
            }

        }

        public static DbType SqlToDbType(this string pSqlType)
        {
            return pSqlType.SqlToType().ToDbType();
        }

        public static object GetDefault(this Type type)
        {
            if (type.IsValueType)
            {
                return Activator.CreateInstance(type);
            }
            return null;
        }

    }
}
0

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

Ahmed
  • 7,148
  • 12
  • 57
  • 96
0

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).

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • It does have to adapt to different schemas. I'm writing a generator that takes in an SP name and gens a C# class from the input and output parameters using SQL-DMO (SQL 2000) – Chris McCall Jun 29 '09 at 14:15
  • That is also a valid approach. Greg already gave a good answer. Normally I'd recommend also considering using Stream oriented types for the large types (n/varchar/varbinary(max) and xml) but you say you're on SQL2K so it doesn't apply). – Remus Rusanu Jun 29 '09 at 14:21
0

Normally I just use the Value property to convert a SqlType to a native .NET type. This does the job most of the time. If I have a corner case, I'll just write a quick helper function.

int i = dataReader.GetSqlInt32(0).Value;
Aaron Daniels
  • 9,563
  • 6
  • 45
  • 58
0

I understand that you're discussing writing a switch statement, but here's an alternate for Sql Server (similar concepts work for other DBs)

Consider using SysObjects to retrieve the full data types and generate your class:

declare @ProcName varchar(255)
select @ProcName='Table, View, or Proc'
SELECT --DISTINCT 
    b.name 
    , c.name Type
    , b.xtype
    , b.length 
    , b.isoutparam
FROM 
    sysObjects a 
INNER JOIN sysCOLUMNs b ON a.id=b.id 
INNER JOIN systypes c ON b.xtype=c.xtype  
WHERE 
    a.name=@ProcName
order by b.colorder

Now you're just enumerating a DataTable instead of the longer statement.

sth
  • 222,467
  • 53
  • 283
  • 367