【问题标题】:Anybody got a C# function that maps the SQL datatype of a column to its CLR equivalent?有人有一个将列的 SQL 数据类型映射到其 CLR 等效项的 C# 函数吗?
【发布时间】:2010-11-06 16:44:10
【问题描述】:

我正坐下来编写一个庞大的 switch() 语句来将 SQL 数据类型转换为 CLR 数据类型,以便从 MSSQL 存储过程生成类。我使用this chart 作为参考。在我深入了解可能需要一整天的时间并且很难完全测试之前,我想打电话给 SO 社区,看看是否有其他人已经在 C# 中编写或找到了一些东西来完成这个看似常见的事情并且肯定是乏味的任务。

【问题讨论】:

  • 我过去曾实现过一个非常相似的系统,但不适用于 C#。我一直想建立这样的东西,但我还没有开始。你的实现是关闭还是开源的?因为我确信我和其他人会对您所描述的开源实现非常感兴趣。
  • 这是用于商业开发的。
  • 这在 2009 年可能还没有,但 System.Web 可能有这里需要的东西:stackoverflow.com/a/28561947/4228193try { return Convert.ChangeType(value_to_convert, Parameter.ConvertDbTypeToTypeCode(SqlMetaData_instance.DbT‌​ype); } 也可用:ConvertTypeCodeToDbType (msdn.microsoft.com/en-us/library/…)

标签: c# types


【解决方案1】:

这是我们使用的。您可能想要调整它(例如可空/不可空类型等),但它应该可以节省您大部分的打字时间。

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");
    }
}

【讨论】:

  • 你是如何利用这个方法的?
  • @user457104 - Erm... 你可以像其他任何方法一样调用它。
  • 不,我的意思是,我不明白你用它做什么。您是否使用返回值来动态创建类型?你用它来比较它和别的东西吗?在代码中,我想在什么情况下将 SqlDbType 转换为 Type?我确信它有很好的用途,但我想不出它。因此,我在问。
  • @user457104 - 我们在为我们的存储过程生成 .NET 包装类的工具中使用它。它确定 SQL 参数类型并使用此函数生成具有相应 CLR 类型的包装器。这真的不是很常见的用例。
  • HierarchyId 在哪里?
【解决方案2】:
    /****** 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;

【讨论】:

  • 处理数据的唯一方法是能够处理元数据。为了能够处理元数据,应该能够使用其数据。为了能够使用其数据,必须正确描述它......
  • 我不敢相信在过去的 4.5 年里没有人发现这一点,但是 SQL bigint 并不等同于 C# short.. 我认为您的意思是 long(又名 Int64)!跨度>
  • varchar 有 NULL 数据类型是否有原因?
  • 好点。我能想到的唯一原因是代码处于“正在进行中的状态”这一事实——即现在没有测试,我凭直觉将其更改为 NOT NULL ......除非有人证明为什么不应该这样做...... .
  • 好表但缺少一列 MSSQL system_type_id
【解决方案3】:
    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;
    }

【讨论】:

  • 有谁知道这里显示的Dictionary.TryGetValue() 这种方法是否比本线程其他地方显示的switch...case 方法更快或更慢?
【解决方案4】:

这是一个可以为空的版本。

    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");
        }
    }

【讨论】:

    【解决方案5】:

    你不需要函数。我想你可能正在寻找

    dt.Columns[i].DataType.UnderlyingSystemType
    

    dt - 数据表

    这将返回相应列的 CLR 类型。 希望这会有所帮助,顺便说一句,这是我在堆栈 overflow

    上的第一个答案

    【讨论】:

      【解决方案6】:

      这并没有直接回答所提出的问题,但它确实回答了一个常见的相关问题。一旦你有了IDataReader,你就可以调用IDataRecord.GetFieldType(int)来“[获取]Type的信息,该信息对应于Object的类型,这将从GetValue返回。”

      【讨论】:

      【解决方案7】:

      我在我的模型中包含了这个扩展(您可以轻松地将字典中的字符串键交换为 Greg 实现的 SqlDbType - 甚至支持两者),并公开一个转换 CLR 类型的属性:

          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));
                  }
              }
          }
      

      【讨论】:

        【解决方案8】:

        你可以试试Wizardby。但是,它从所谓的“本机”数据类型映射到 DbType,然后将其转换为 CLR 类型是微不足道的。如果适合,您将需要一个合适的 IDbTypeMapper - SqlServer2000TypeMapperSqlServer2005TypeMapper

        【讨论】:

          【解决方案9】:
          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;
                  }
          
              }
          }
          

          【讨论】:

            【解决方案10】:

            我认为没有内置的,但您可以使用 VS 为您的表生成类,然后尝试编辑它们

            【讨论】:

              【解决方案11】:

              为什么不创建一个类型化的数据集并让 VS 设计器为您做映射呢?除非项目必须在运行时适应不同的模式,否则您应该使用代码生成技术来创建您的类,无论是内置设计器(即类型化数据集)还是自定义设计器(schema->XML->XSLT->. c)。

              【讨论】:

              • 它确实必须适应不同的模式。我正在编写一个生成器,它接收一个 SP 名称并使用 SQL-DMO(SQL 2000)从输入和输出参数生成一个 C# 类
              • 这也是一种有效的方法。格雷格已经给出了很好的答案。通常,我建议还考虑对大型类型(n/varchar/varbinary(max) 和 xml)使用面向流的类型,但您说您使用的是 SQL2K,因此它不适用)。
              【解决方案12】:

              通常我只使用 Value 属性将 SqlType 转换为原生 .NET 类型。这在大多数情况下都可以完成工作。如果我有一个极端情况,我会写一个快速帮助函数。

              int i = dataReader.GetSqlInt32(0).Value;
              

              【讨论】:

                【解决方案13】:

                我了解到您正在讨论编写 switch 语句,但这里是 Sql Server 的替代方法(类似的概念适用于其他数据库)

                考虑使用 SysObjects 检索完整的数据类型并生成您的类:

                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
                

                现在您只是在枚举一个 DataTable 而不是更长的语句。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-22
                  • 2010-09-30
                  • 1970-01-01
                  • 2011-07-11
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多