欢迎投稿

今日深度:

如何用T4模板生成数据实体(1)(2)

在声明 Table / View / TableType 的时候:

  1. CREATE TYPE TMessageReceiver AS TABLE(  
  2.     SendType VARCHAR(10) NOT NULL,  
  3.     Receiver NVARCHAR(128) NOT NULL 
  4. )  
  5. GO  
  6. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息接收人, 相同SendType 和Recever 只能出现一次' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TYPE',@level1name=N'TMessageReceiver' 
  7. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息发送类型EML(QQ, MSN留扩展)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TYPE',@level1name=N'TMessageReceiver', @level2type=N'COLUMN',@level2name=N'SendType' 
  8. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'接收地址,跟据SendType' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TYPE',@level1name=N'TMessageReceiver', @level2type=N'COLUMN',@level2name=N'Receiver' 
  9. GO  

------------

  1. CREATE TABLE LoginPolicy(  
  2.     PolicyID INT IDENTITY(1,1) NOT NULL,  
  3.     UnfreezeTime INT NOT NULL DEFAULT 30,  
  4.     MaxFailedCount INT NOT NULL DEFAULT 5,  
  5.     EnableLoginPolicy BIT DEFAULT 1, -- 0 : 不启用, 1:启用  
  6.     CreateTime DATETIME NOT NULL DEFAULT GETDATE(),  
  7.     Creator NVARCHAR(30),  
  8.     CONSTRAINT LoginPolicy_PK PRIMARY KEY (PolicyID)  
  9. )  
  10. GO  
  11. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'登陆策略' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LoginPolicy' 
  12. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'自动编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LoginPolicy', @level2type=N'COLUMN',@level2name=N'PolicyID' 
  13. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'解冻时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LoginPolicy', @level2type=N'COLUMN',@level2name=N'UnfreezeTime' 
  14. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'最大失败次数' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LoginPolicy', @level2type=N'COLUMN',@level2name=N'MaxFailedCount' 
  15. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否启用登陆策略' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LoginPolicy', @level2type=N'COLUMN',@level2name=N'EnableLoginPolicy' 
  16. GO  

声明存储过程:

  1. CREATE PROCEDURE SendMsg  
  2.     @Title NVARCHAR(100),  
  3.     @Ctx NVARCHAR(500),  
  4.     @UserID INT,  
  5.     @FromIP BIGINT,  
  6.     @IntranetIP BIGINT,  
  7.     @IsPublic BIGINT,  
  8.     @Receiver TMessageReceiver READONLY  
  9. AS 
  10. BEGIN 
  11.     -- 表变量,用以存储新增的主表ID  
  12.     DECLARE @T AS TABLE (ID INT)  
  13.     BEGIN TRAN NewMsg  
  14.     BEGIN TRY  
  15.         -- 写入主表  
  16.         INSERT INTO [Message]  
  17.         (Title, Ctx, UserID, FromIP, IntranetIP, IsPublic)  
  18.         OUTPUT INSERTED.MessageID INTO @T  
  19.         VALUES 
  20.         (@Title, @Ctx, @UserID, @FromIP, @IntranetIP , @IsPublic )  
  21.         -- 取出新增数据的ID  
  22.         DECLARE @MessageID INT 
  23.         SELECT TOP 1 @MessageID = ID FROM @T  
  24.         -- 写子表, 这里要改动一下,相同的只保留一条  
  25.         INSERT INTO MessageReceiver  
  26.             (MessageID, SendType, Receiver )  
  27.         SELECT 
  28.             @MessageID, R.SendType, R.Receiver  
  29.         FROM 
  30.             @Receiver R  
  31.     END TRY  
  32.     BEGIN CATCH  
  33.         ROLLBACK TRAN NewMsg  
  34.         RETURN 2 -- DatabaseError  
  35.     END CATCH  
  36.     COMMIT TRAN NewMsg  
  37.     RETURN 0  
  38. END 
  39. GO  
  40. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'发送消息' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg' 
  41. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息标题' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@Title' 
  42. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息内容' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@Ctx' 
  43. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'用户ID' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@UserID' 
  44. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'发消息的IP' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@FromIP' 
  45. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'发消息的内网IP,用于扩展' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@IntranetIP' 
  46. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否公开' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@IsPublic' 
  47. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息接收者,表变量' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'SendMsg', @level2type=N'PARAMETER', @level2name = '@Receiver' 
  48. GO 

这些 MS_Description 的 value 会做为注释写到生成的代码里。

实现T4模板就很简单了,就是把下面几个SQL的结果取出来,在自由的组合一下:

  1. WITH Entities AS (  
  2.     SELECT 
  3.         Table_catalog AS [Database]  
  4.         , table_schema [Owner]  
  5.         , table_name [Name]  
  6.         , 'Table' [Type]  
  7.         ,OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME) ID  
  8.     FROM 
  9.         INFORMATION_SCHEMA.TABLES  
  10.     WHERE 
  11.         TABLE_TYPE='BASE TABLE' 
  12.     UNION ALL 
  13.     SELECT 
  14.         Table_catalog  
  15.         , table_schema  
  16.         , table_name  
  17.         , 'View' 
  18.         , OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME) ID  
  19.     FROM 
  20.         information_schema.views  
  21.     UNION ALL 
  22.     SELECT 
  23.         DB_NAME()  
  24.         , SCHEMA_NAME(schema_id)  
  25.         , name 
  26.         , 'TableType' 
  27.         , user_type_id  
  28.     FROM 
  29.         sys.table_types  
  30. )  
  31. SELECT 
  32.     E.*  
  33.     , P.value AS [DESC]  
  34. FROM 
  35.     Entities E  
  36.     LEFT JOIN sys.extended_properties P ON E.ID = P.major_id AND P.minor_id = 0 

Table / View / TableType

字段:

  1. SELECT 
  2.     DB_NAME() AS [Database]  
  3.     ,COALESCE( SCHEMA_NAME(T.Schema_id), OBJECT_SCHEMA_NAME(C.object_id)) AS Owner  
  4.     ,COALESCE( T.Name, OBJECT_NAME(c.OBJECT_ID)) AS Parent  
  5.     ,C.column_id AS OrdinalPosition  
  6.     ,C.name AS Name 
  7.     ,TYPE_NAME(c.user_type_id) AS DataType  
  8.     ,D.definition AS DefaultSetting  
  9.     , C.is_nullable AS IsNullable  
  10.     , C.max_length AS MaxLength  
  11.     , COLUMNPROPERTY( C.OBJECT_ID , C.Name ,'PRECISION'AS [Precision-- 用于判断NVARCHAR 实际长度的  
  12.     --,C.Object_id, P.major_id, P.minor_id  
  13.     ,P.Value AS [DESC]  
  14. FROM 
  15.     sys.columns C  
  16.     LEFT JOIN sys.table_types T ON T.type_table_object_id = C.object_ID  
  17.     LEFT JOIN sys.default_constraints D ON C.object_id = D.parent_object_id AND D.parent_column_id = C.Column_id  
  18.     LEFT JOIN sys.extended_properties P ON (P.major_id = C.OBJECT_ID OR P.major_id = T.User_type_id ) AND P.minor_id = C.COLUMN_ID AND P.name = 'MS_Description' 
  19. WHERE 
  20.     COALESCE( SCHEMA_NAME(T.Schema_id), OBJECT_SCHEMA_NAME(C.object_id)) = 'dbo' 

存储过程:

  1. SELECT 
  2.     SCHEMA_NAME(P.schema_id) AS Owner  
  3.     , P.Name 
  4.     , PP.Value AS [Desc]  
  5. FROM 
  6.     sys.procedures P  
  7.     LEFT JOIN sys.extended_properties PP ON P.object_id = PP.major_id AND PP.minor_id = 0 

存储过程的参数:

  1. SELECT 
  2.     SCHEMA_NAME( P.[schema_id] ) AS [Schema]  
  3.     ,P.Name AS [Proc]  
  4.     ,PA.Name 
  5.     , (SELECT COUNT(1) FROM sys.table_types WHERE user_type_id = PA.user_type_id) AS IsTableType  
  6.     ,TYPE_NAME(PA.user_type_id) AS DataType  
  7.     , PA.max_length AS MaxLength  
  8.     , COLUMNPROPERTY( PA.OBJECT_ID , PA.Name ,'PRECISION'AS [Precision-- 用于判断NVARCHAR 实际长度的  
  9.     , PA.is_output AS IsOutput  
  10.     , PP.value AS [Desc]  
  11. FROM 
  12.     sys.procedures P  
  13.     INNER JOIN sys.parameters PA ON P.object_id = PA.object_id  
  14.     LEFT JOIN sys.extended_properties PP ON PA.object_id = PP.major_id AND PA.parameter_id = PP.minor_id  
  15. ORDER BY 
  16.     PA.Object_id, PA.Parameter_id 

源代码包:http://files.cnblogs.com/xling/ExecuteT4.7z

这个包里有一个如何用程序运行T4模板的示例,加这个是因为同事问我如何用代码去执行T4模板,昨晚K歌完到家12点半(跟经理道别),洗完澡后,我从以前写的代码里翻出来的,稍稍做了点修改。还有一份数据字典导出模板.

另外需要注意的是:

1, Microsoft.VisualStudio.TextTemplating.dll 这个 DLL,如果你装的是VS2010 就默认装了这个。如果是VS2008, 需要从:Visual Studio 2008 SDK 1.1 里找

2, 如图

遗留的问题:

有些默认值没有处理好,比如对DateTime字段只处理了这种情况: GETDATE() 或 ‘2011-01-01’ , 其它的我暂时没有遇到,没有做处理。

存储过程的 TableType 参数,我简单的映射为 DbType.Object ,还没有验证这样是否可行。

后面我会把这些都修正的,如果你有兴趣的话,可以留意。


www.htsjk.Com true http://www.htsjk.com/shujukukf/17019.html NewsArticle 在声明 Table / View / TableType 的时候: CREATE TYPETMessageReceiver AS TABLE ( SendType VARCHAR (10) NOT NULL , ReceiverNVARCHAR(128) NOT NULL ) GO EXEC sys.sp_addextendedproperty@ name =N 'MS...
相关文章
    暂无相关文章
评论暂时关闭