如何以编程方式将SQL数据类型转换为.Net数据类型?

时间:2010-03-21 19:20:48

标签: .net sql-server code-generation

任何人都可以告诉我一种将SQL Server数据类型(例如varchar)转换为.Net数据类型(例如String)的方法。我假设自动转换是不可能的? 我有一个'EntityProperty'对象,并希望它有一个适当的'Type'属性(字符串,十进制,int32等),此时此属性只是一个字符串 - 例如'int32'。

一点背景:我在内部代码生成应用程序中使用SQL DMO来查询数据库并从数据库生成基于DAL的存储过程。作为一个内部应用程序,我可以采取相当多的快捷方式,并做出相当多的假设。为了使应用程序正常运行,此数据类型转换由Select Case语句处理,该语句只将类型转换为字符串并根据这些字符串生成一组属性,但我希望能够更灵活地处理类型(使用TypeOf等)。

有人在做类似的事吗?

我知道EF,nHibernate,Subsonic等可以为我做这一切,但在这种情况下,出于各种原因,我不得不自己动手。 :)

5 个答案:

答案 0 :(得分:6)

硬编码是一件坏事的原因只是因为当你把代码放在代码中改变时,它很烦人(并且很昂贵) - 没有其他原因。不会发生变化的事情,如pi或工作日列表,可能会根据您的内容进行硬编码,因此您不会产生任何额外的开发成本。

所以这个问题不是关于不维护手动映射表 - 如果必要的话还要在代码中 - 因为它只是在一个地方维护映射表。

几年前我们推出了自己的数据访问类。当然,我们手动(在VB.NET Select Case语句中)从.NET类型转换为SQL类型。当我们不得不添加Enum类型时,我认为它改变了一次。

这是一次,大约四年。我们平均每周发布一次 - 猜测我们对于硬编码.NET的“开销”有多担心 - > SQL类型映射?

在一个地方做。确保一切都使用它。然后忘记它。还有其他更难解决的问题。

答案 1 :(得分:4)

无法“自动”执行类型转换。实际上,大多数ORM库依赖于目标实体类中使用的实际属性类型来执行映射。

我会使用Linq to SQL文档中的SQL-CLR Type Mapping作为构建手动映射代码的起点。在许多情况下,将有多个有效的映射。

答案 2 :(得分:2)

或者您可以使用自动翻译的表格,而不是使用这些值(这是初步的,未经过大量测试......):

USED IT DIRECTLY FOR CLASS GENERATION 或者即使你喜欢generate the classes for the whole db

        /****** 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'short', 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;

答案 3 :(得分:2)

我在另一个方向做了类似的事情,使用System.Type对象的Dictionary到SQL类型名称。

答案 4 :(得分:1)

  

我知道EF,nHibernate,Subsonic等可以为我做这一切,但在这种情况下,出于各种原因,我不得不自己动手。 :)

为什么不使用SubSonic或其他ORM映射工具之一来定义Sql数据类型和.Net数据类型之间的工作转换 - 然后使用这些转换信息作为基础来推广您自己的解决方案?

我假设你不能在解决方案中使用第三方软件 - 但你可以找到解决方案。