综合应用WPF/WCF/WF/LINQ之二十七:代码生成器之DBMLToProcedure

简介:
本存储过程代码生成器能处理如下几种形式的存储过程:
  1、形如InsertTableName的存储过程,用于插入某条记录。
  2、形如UpdateTableNameByFieldName的存储过程,用于根据某个字段更新某条记录。
  3、形如DeleteTableNameByFieldName的存储过程,用于根据某个字段删除某条记录。
  4、形如GetTableNames的存储过程,用于查询所有记录。
  5、形如GetTableNamesByFieldName的存储过程,用于根据某个字段查询记录。
  6、形如GetTableNamesByPage的存储过程,用于根据页码查询记录。
  7、形如GetTableNamesByFilter的存储过程,用于根据过滤条件、页码查询记录。
  在存储过程没有过多业务逻辑的情况下,一般上述集中形式的存储过程即能满足一般系统的需要。如果您需要支持更多的形式,请自行修改代码。
  各种形式的存储过程举例如下:
  1、形如InsertTableName的存储过程。对该存储过程,我们主要需要获取该表的字段名、类型和长度等。在以前,我们需要通过读取数据的Schema的方式来获得字段的这些属性,现在有了LINQ,我就可以直接从DBML文件中获取了。
    1  IF EXISTS ( SELECT FROM sysobjects  WHERE type =  'P'  AND name 'InsertFunction')
    2      BEGIN
    3          DROP Procedure [InsertFunction]
    4      END
    5 
    6 GO
    7 
    8  CREATE Procedure [InsertFunction]
    9     (
   10         @FunctionId  Int NULL,
   11         @FunctionName  NVarChar(50) =  NULL,
   12         @FunctionDescription  NVarChar(255) =  NULL
   13     )
   14 
   15  AS
   16 
   17      BEGIN
   18          INSERT INTO [Function] ([FunctionId],
   19                                 [FunctionName],
   20                                 [FunctionDescription])
   21          VALUES (@FunctionId,
   22                 @FunctionName,
   23                 @FunctionDescription)
   24      END
   25 
   26 GO
  获取了足够的信息后,这个存储过程的拼凑就可以完成了。主体拼凑代码如下,其中24和16用于生成空格,以便看到上面每个字段分一行的整齐代码。
    1         strContentes +=  string.Format( "        INSERT INTO [{0}] ({1})" +  "\n", table, strColumns.GetColumns(24 + table.Length));
    2         strContentes +=  string.Format( "        VALUES ({0})" +  "\n", strColumns.GetVariables(16));
  2、形如GetTableNamesByFilter的存储过程。在有很多可选过滤条件的情况下,我们不可能为每一种组合创建一个存储过程,这时,我们可以采用拼凑Where后面的SQL语句的方式实现查询。这时,我们除了跟上一个存储过程一样获取字段信息外,还需要处理翻页、拼凑SQL语句等。我们可以采用嵌套Select语句的方式实现拼凑和翻页。
    1  IF EXISTS ( SELECT FROM sysobjects  WHERE type =  'P'  AND name 'GetFunctionsByFilter')
    2      BEGIN
    3          DROP Procedure [GetFunctionsByFilter]
    4      END
    5 
    6 GO
    7 
    8  CREATE Procedure [GetFunctionsByFilter]
    9     (
   10         @FunctionName  NVarChar(50) =  NULL,
   11         @PageSize  Int NULL,
   12         @PageIndex  Int NULL,
   13         @RecordCount  Int NULL OUTPUT
   14     )
   15 
   16  AS
   17 
   18      BEGIN
   19          DECLARE @MinIndex  Int
   20          DECLARE @MaxIndex  Int
   21          SET @MinIndex = (@PageIndex - 1) * @PageSize + 1
   22          SET @MaxIndex = @MinIndex + @PageSize - 1
   23 
   24          DECLARE @Where  NVarChar( MAX)
   25          SET @Where =  '0 = 0'
   26          IF @FunctionName  IS NOT NULL
   27              SET @Where = @Where +  ' AND [Function].[FunctionName] LIKE ''%' + @FunctionName +  '%'''
   28 
   29          DECLARE @Record  NVarChar( MAX)
   30          SET @Record =  'SELECT ROW_NUMBER() OVER(ORDER BY [Function].[FunctionId]) AS [Index],
   31                                [Function].[FunctionId],
   32                                [Function].[FunctionName],
   33                                [Function].[FunctionDescription]
   34                         FROM [Function]
   35                         WHERE' ' ' + @Where
   36 
   37          DECLARE @Sql  NVarChar( MAX)
   38          SET @Sql =  'SELECT @RecordCount = COUNT(*)
   39                      FROM (' + @Record +  ') DERIVEDTBL
   40 
   41                      SELECT [FunctionId],
   42                             [FunctionName],
   43                             [FunctionDescription]
   44                      FROM (' + @Record +  ') DERIVEDTBL
   45                      WHERE [Index] >= @MinIndex AND [Index] <= @MaxIndex'
   46 
   47          DECLARE @Parameter  NVarChar( MAX)
   48          SET @Parameter =  '@MinIndex Int, @MaxIndex Int, @RecordCount Int OUTPUT'
   49 
   50          EXEC sp_executesql @Sql, @Parameter, @MinIndex, @MaxIndex, @RecordCount  OUTPUT
   51      END
   52 
   53 GO
  获取了足够的信息后,这个存储过程的拼凑就可以完成了。主体拼凑代码如下。值得注意的是,当可选参数为String类型时,您需要处理脚本注入的问题(笔者这里并未处理)。
    1     strContentes = strContentes +  "        DECLARE @MinIndex Int" +  "\n";
    2     strContentes = strContentes +  "        DECLARE @MaxIndex Int" +  "\n";
    3     strContentes = strContentes +  "        SET @MinIndex = (@PageIndex - 1) * @PageSize + 1" +  "\n";
    4     strContentes = strContentes +  "        SET @MaxIndex = @MinIndex + @PageSize - 1" +  "\n";
    5     strContentes = strContentes +  "        " +  "\n";
    6     strContentes = strContentes +  "        DECLARE @Where NVarChar(MAX)" +  "\n";
    7     strContentes = strContentes +  "        SET @Where = '0 = 0'" +  "\n";
    8 
    9      for ( int i = 0; i < method.GetParameters().Length - 3; i++)
   10     {
   11         strContentes +=  string.Format( "        IF @{0} IS NOT NULL" +  "\n", method.GetParameters()[i].GetName());
   12 
   13          if (method.GetParameters()[i].ParameterType.ToSqlDbType().ToString() ==  "NVarChar")
   14         {
   15             strContentes +=  string.Format( "            SET @Where = @Where + ' AND [{0}].[{1}] LIKE ''%' + @{2} + '%'''" +  "\n", table, method.GetParameters()[i].GetName(), method.GetParameters()[i].GetName());
   16         }
   17          else  if (method.GetParameters()[i].ParameterType.ToSqlDbType().ToString() ==  "DateTime" && method.GetParameters()[i].GetName().StartsWith( "Begin") ==  true)
   18         {
   19             strContentes +=  string.Format( "            SET @Where = @Where + ' AND [{0}].[{1}] >= ''' + CONVERT(NVarChar, @{2}, 101) + ' ' + '00:00:00' + ''''" +  "\n", table, method.GetParameters()[i].GetName().Substring(5), method.GetParameters()[i].GetName());
   20         }
   21          else  if (method.GetParameters()[i].ParameterType.ToSqlDbType().ToString() ==  "DateTime" && method.GetParameters()[i].GetName().StartsWith( "End") ==  true)
   22         {
   23             strContentes +=  string.Format( "            SET @Where = @Where + ' AND [{0}].[{1}] <= ''' + CONVERT(NVarChar, @{2}, 101) + ' ' + '23:59:59' + ''''" +  "\n", table, method.GetParameters()[i].GetName().Substring(3), method.GetParameters()[i].GetName());
   24         }
   25          else
   26         {
   27             strContentes +=  string.Format( "            SET @Where = @Where + ' AND [{0}].[{1}] = ''' + CONVERT(NVarChar, @{2}) + ''''" +  "\n", table, method.GetParameters()[i].GetName(), method.GetParameters()[i].GetName());
   28         }
   29     }
   30 
   31     strContentes = strContentes +  "        " +  "\n";
   32     strContentes = strContentes +  "        DECLARE @Record NVarChar(MAX)" +  "\n";
   33     strContentes +=  string.Format( "        SET @Record = 'SELECT ROW_NUMBER() OVER(ORDER BY [{0}].[{1}]) AS [Index]," +  "\n", table, strKey);
   34     strContentes +=  string.Format( "                              {0}" +  "\n", strColumns.GetColumns(table, infos, 30,  true));
   35     strContentes +=  string.Format( "                       FROM {0}" +  "\n", infos.GetFroms(table, 23));
   36     strContentes = strContentes +  "                       WHERE' + ' ' + @Where" +  "\n";
   37     strContentes = strContentes +  "        " +  "\n";
   38     strContentes = strContentes +  "        DECLARE @Sql NVarChar(MAX)" +  "\n";
   39     strContentes = strContentes +  "        SET @Sql = 'SELECT @RecordCount = COUNT(*)" +  "\n";
   40     strContentes = strContentes +  "                    FROM (' + @Record + ') DERIVEDTBL" +  "\n";
   41     strContentes = strContentes +  "                    " +  "\n";
   42     strContentes +=  string.Format( "                    SELECT {0}" +  "\n", strColumns.GetColumns(table, infos, 27,  false));
   43     strContentes = strContentes +  "                    FROM (' + @Record + ') DERIVEDTBL" +  "\n";
   44     strContentes = strContentes +  "                    WHERE [Index] >= @MinIndex AND [Index] <= @MaxIndex'" +  "\n";
   45     strContentes = strContentes +  "        " +  "\n";
   46     strContentes = strContentes +  "        DECLARE @Parameter NVarChar(MAX)" +  "\n";
   47     strContentes = strContentes +  "        SET @Parameter = '@MinIndex Int, @MaxIndex Int, @RecordCount Int OUTPUT'" +  "\n";
   48     strContentes = strContentes +  "        " +  "\n";
   49     strContentes = strContentes +  "        EXEC sp_executesql @Sql, @Parameter, @MinIndex, @MaxIndex, @RecordCount OUTPUT" +  "\n";
  其它类型的存储过程我就不一一列举。
  在开始使用这个代码生成器之前,请先手工完成Eallies.OA.DAL.Interface这个项目,这个项目包含所有的DAL层需要实现的接口。这个代码生成将根据这个接口生成相应名称、参数等的存储过程。
  本存储过程代码生成器的调用方法请参考Eallies.OA.Generator目录下的GenerateProcedure.bat文件。




本文转自 Eallies 51CTO博客,原文链接:http://blog.51cto.com/eallies/79013,如需转载请自行联系原作者
目录
相关文章
|
开发框架 前端开发 JavaScript
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(12) -- 使用代码生成工具Database2Sharp生成WPF界面代码
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(12) -- 使用代码生成工具Database2Sharp生成WPF界面代码
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(12) -- 使用代码生成工具Database2Sharp生成WPF界面代码
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
149 0
|
安全 数据库连接 数据库
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构。该架构的项层为服务模型层。 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案。且能与已有系统兼容写作。 简单概括就是:一组数据通信的应用程序开发接口。
284 0
|
C++
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
263 0
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF使用纯代码的方式进行服务寄宿
服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用,除去上面的两种寄宿方式,还可以以纯代码的方式实现服务的寄宿工作。
989 0