• CodeSmith对数据库中表的操作(转)


     

    CodeSmith对数据库中表的操作
    在与数据库进行交互时, 我们使用到了一个CodeSmith自带的组件SchemaExplorer,利用这个组件我们可以访问数据库的数据表、存储过程、视图等,并可以得到相应的数据类型、标识列、列的(字段)

    名称等信息。
    <%@ Assembly Name="SchemaExplorer" %>
    <%@ Import Namespace="SchemaExplorer" %>

    SchemaExplorer.TableSchema类:是CodeSmith中自带的一个类,它描述表的结构。
    Name属性:表的名称
    Columns属性:表中列的集合
    ExtendedProperties属性:表中指定列的扩展信息
    ForeignKeyColumns属性:表的一个外键列的集合
    ForeignKeys属性:表的外键集合
    HasPrimaryKey属性:返回表中是否存在主键
    NonForeignKeyColumns属性:表中非外键列的集合
    NonKeyColumns属性:表中非外键,非主键列的集合
    NonPrimaryKeyColumns属性:表中非主键列的集合
    PrimaryKey属性:表中的主键

    表中指定列的扩展属性 (ExtendedProperties属性):
      CS_IsIdentity:自增长列
      CS_IsComputed :计算列
      CS_IdentitySeed :自增长列的起始值
      CS_IdentityIncrement :自增长列的步长
      CS_Default :列的默认值

    例如:SQL Server定义了一个扩展属性来标识表中的唯一标识字段,在模版中可以这样写:
    Identity Field =<% foreach(ColumnSchema cs in SourceTable.Columns) {
             if( ((bool)cs.ExtendedProperties["CS_IsIdentity"].Value) == true)
             {
                   Response.Write(cs.Name);
             }
    }
    %>

    要访问数据库中表的信息首选需要在CodeSmith中创建数据库的链接,步骤如下:
    1、点击Schema Explorer中的Manage Data Sours图标


    2、点击“add”添加一个新链接


    3、添加完毕后在Schema Explorer中会出现新建的数据源

    下面利用CodeSmith根据数据库的结构来生成存储过程
    第一步还是指明模板使用的语言和生成的目标语言。
    <%@ CodeTemplate Language="C#" TargetLanguage="T-SQL" Description="Generates a update stored procedure." %>
    第二步要加载使用访问数据库的组件SchemaExplorer,并声明其使用的命名空间。
    <%@ Assembly Name="SchemaExplorer" %>
    <%@ Import Namespace="SchemaExplorer" %>
    第三步定义一个存储表名称使用的变量,然后指明这个变量类型为SchemaExplorer.TableSchema,这样我们可以通过这个变量得到相应的表的信息。
    <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" %>
    第四步下面利用循环语句遍历表的各个列,拼出存储过程需要传递的参数,以列名作为参数名。
    <% for (int i = 0; i < SourceTable.Columns.Count; i++) { %>
    <%= GetSqlParameterStatement(SourceTable.Columns[i]) %><% if (i < SourceTable.Columns.Count - 1) { %>,<% } %>
    <% } %>
    其中的GetSqlParameters是自定义的CodeSmith中的脚本函数,形参接收列对象,返回拼完的参数。
    <script runat="template">
    public string CreateParams(ColumnSchema column) //接收列对象
    {
       string strparams="@";
       strparams += column.Name+" "+column.NativeType.ToString();//在列名前加@符号拼成参数名
       switch(column.DataType) //根据列对象类型,为参数定义其类型及长度。
       {
        case DbType.Decimal:
        {
         strparams += "("+column.Precision.ToString()+","+column.Scale.ToString()+")";
         break;
        }
        default:
        {
         strparams += "("+column.Size+")";
         break;
        }
       }
       return strparams;
    }
    </script>
    第五步下面来生成需要更新的字段,更新时仅能更新非主键字段的值,在SchemaExplorer中支持这种区别,使用SourceTable.NonPrimaryKeyColumns即可得到非主键字段的集合。
    UPDATE [<%= SourceTable.Name %>] SET
           <% for (int i = 0; i < SourceTable.NonPrimaryKeyColumns.Count; i++) { %>
           [<%= SourceTable.NonPrimaryKeyColumns[i].Name %>] = @<%= SourceTable.NonPrimaryKeyColumns[i].Name %><% if (i < SourceTable.NonPrimaryKeyColumns.Count - 1) { %>,<% } %>
           <% } %>
    第六步然后再使用SourceTable.PrimaryKey.MemberColumns得到数据表中的主键集合,生成更新条件
    WHERE
           <% for (int i = 0; i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %>
           <% if (i > 0) { %>AND <% } %>
           [<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>] = @<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>
           <% } %>

    生成表的添加存储过程
    <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="" Inherits="" Debug="False" Description="Template description here." %>
    <%@ Property Name="STable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Context"%>
    <%@ Assembly Name="SchemaExplorer" %>
    <%@ Import Namespace="SchemaExplorer" %>
    create procedure UP_<%=STable.Name.ToUpper()%>_INSERT
    <%for(int i=0;i<STable.Columns.Count;i++){%>
    <%if((bool)STable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value==true) continue;%><%--跳过自增长列--%>
    <%=CreateParams(STable.Columns[i])%><%if(i<STable.Columns.Count-1){%>,<%}%>
    <%}%>
    as
    insert into <%=STable.Name%> (<%for(int i=0;i<STable.Columns.Count;i++){%>
    <%--跳过自增长列--%>
    <%if((bool)STable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value==true) continue;%>
    <%--输出列名列表,如果多列用逗号隔开--%>
    <%=STable.Columns[i].Name%><%if(i<STable.Columns.Count-1)%>,<%} %>)
    values(<%for(int i=0;i<STable.Columns.Count;i++){%>
    <%--跳过自增长列--%>
    <%if((bool)STable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value==true) continue;%>
    <%--加上参数名(在列名前加@),如果有多个列值用逗号隔开--%>
    @<%=STable.Columns[i].Name%><%if(i<STable.Columns.Count-1){%>,<%}%><%}%>)
    go
    <%--生成参数列表的CodeSmith脚本--%>
    <script runat="template">
    public string CreateParams(ColumnSchema column)
    {
    string strparams="@";
    strparams += column.Name+" "+column.NativeType;
    switch(column.DataType)
    {
       case DbType.Decimal:
       {
        strparams += "("+column.Precision+","+column.Scale+")";
        break;
       }
       default:
       {
        strparams += "("+column.Size+")";
        break;
       }
    }
    return strparams;
    }
    </script>
    CodeSmith的执行结果:

    生成表的更新存储过程
    <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="" Inherits="" Debug="False" Description="Generate a update stored procedure" %>
    <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Context" %>
    <%@ Assembly Name="SchemaExplorer" %>
    <%@ Import Namespace="SchemaExplorer" %>

    create procedure UP_<%=SourceTable.Name.ToUpper()%>_UPDATE
    <%for(int i=0;i<SourceTable.Columns.Count;i++){ if((bool)SourceTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value==true) continue;%>
    <%=CreateParams(SourceTable.Columns[i])%><%if(i<SourceTable.Columns.Count-1){%>,<%}%>
    <%}%>
    as
    update <%=SourceTable.Name%> set
    <%for(int i=0;i<SourceTable.NonPrimaryKeyColumns.Count;i++){ if((bool)SourceTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value == true) continue;%>
    <%=SourceTable.NonPrimaryKeyColumns[i].Name%>=@<%=SourceTable.NonPrimaryKeyColumns[i].Name%><%if(i<SourceTable.NonPrimaryKeyColumns.Count-1){%>,<%}%>
    <%}%>
    where
    <%for(int i=0;i<SourceTable.PrimaryKey.MemberColumns.Count;i++){%>
    <%if(i>0){ %> and <% }%>
    <%=SourceTable.PrimaryKey.MemberColumns[i].Name%>=@<%=SourceTable.PrimaryKey.MemberColumns[i].Name%>
    <%}%>
    go
    <script runat="template">
    public string CreateParams(ColumnSchema column)
    {
    string strparams="@";
    strparams += column.Name+" "+column.NativeType.ToString();
    switch(column.DataType)
    {
       case DbType.Decimal:
       {
        strparams += "("+column.Precision.ToString()+","+column.Scale.ToString()+")";
        break;
       }
       default:
       {
        strparams += "("+column.Size+")";
        break;
       }
    }
    return strparams;
    }
    </script>
    CodeSmith的执行结果


     
  • 相关阅读:
    你都这么拼了,面试官TM怎么还是无动于衷
    js中string转map的方法
    如何使用jmeter做一个功能的性能测试
    如何看待远程办公?
    vue.js指令v-for使用以及下标索引的获取
    v-charts x轴字体斜显示
    Linux-(inotify-tools&rsync)
    Linux-(type,vim)
    zab协议
    数据库的规范一览
  • 原文地址:https://www.cnblogs.com/kingwangzhen/p/1723119.html
Copyright © 2020-2023  润新知