• C#:CodeSmith根据数据库中的表创建C#数据模型Model + 因为没有钱买正版,所以附加自己写的小代码


    对于C#面向对象的思想,我们习惯于将数据库中的表创建对应的数据模型;

    但假如数据表很多时,我们手动增加模型类会显得很浪费时间;

    这个时候有些人会用微软提供的EntityFrameWork,这个框架很强大,编写代码效率也很高,但很由于性能差,在复杂查询的时候生成的sql脚本效率不是很高,所以有的时候不会去使用它;

    这个时候就会有CodeSmith来协助我们去完成那些费时费力的工作:

    CodeSmith如何使用,网上也有很详细的介绍了,下面代码只是简单介绍

    属性SourceDataBase是连接的数据库,CodeSmith提供连接数据库的方法很方便

    属性NameSpace顾名思义就是命名空间

      1 <%-- 
      2 Name:批量生成实体类
      3 Author: TitanChen
      4 Description:批量将数据库中的表结构生成数据模型 
      5 --%>
      6 <%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Template description here." %>
      7 <%@ Assembly Name="SchemaExplorer" %>
      8 <%@ Import Namespace="SchemaExplorer" %>
      9 <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Category="Context" %>
     10 <%@ Property Name="NameSpace" Type="String" Category="参数" Description="命名空间" Default="Blog.Core.Model" Optional="True"%>
     11 <%@ Import Namespace="System.Text.RegularExpressions" %>
     12 using System;
     13 using System.Collections.Generic;
     14 using System.Text;
     15  
     16 namespace <%=NameSpace%>
     17 {
     18     <% foreach(TableSchema SourceTable in SourceDatabase.Tables) { %>
     19     /// <summary>
     20     /// <%=GetClassName(SourceTable) +"模型"%>
     21     /// </summary>
     22     [Serializable]
     23     public class <%=GetClassName(SourceTable) %> : BaseModel
     24     {   
     25         /// <summary>
     26         /// 表名
     27         /// </summary>
     28         public static readonly string TableName = "<%=GetClassName(SourceTable) %>";
     29         
     30         /// <summary>
     31         /// 构造函数
     32         /// </summary>
     33         public <%=GetClassName(SourceTable) %>() : base(TableName)
     34         {
     35         }
     36         
     37         private Guid Id = Guid.Empty;
     38         <% foreach (ColumnSchema column in SourceTable.Columns) {%>
     39         /// <summary>
     40         /// <%=column.Description %>
     41         /// </summary>
     42         <% if(column.IsPrimaryKeyMember){ %>
     43             public Guid <%= GetPascalName(column) %> 
     44             {
     45                 get{ return Id;}
     46                 set
     47                 {
     48                     Id = value;
     49                     if (value != null)
     50                     {
     51                         base.BaseId = value;
     52                     }
     53                 }
     54             }
     55             
     56         <% }else{ %>
     57             public <%=GetCSharpVariableType(column) %> <%=GetPascalName(column) %> { get; set; }
     58             
     59         <% } %>
     60         <% }%>
     61     }
     62     
     63     /// <summary>
     64     /// <%=GetClassName(SourceTable) +"数据模型"%>
     65     /// </summary>
     66     [Serializable]
     67     public class <%=GetClassName(SourceTable)+"ListData" %>
     68     {   
     69         /// <summary>
     70         /// 总记录数
     71         /// </summary>
     72         public int RecordCount { get; set; }
     73         
     74         /// <summary>
     75         /// 数据列表
     76         /// </summary>
     77         public List<<%=GetClassName(SourceTable)+"ListModel" %>> RecordList { get; set; }
     78     }
     79     
     80     /// <summary>
     81     /// <%=GetClassName(SourceTable) +"列表模型"%>
     82     /// </summary>
     83     [Serializable]
     84     public class <%=GetClassName(SourceTable)+"ListModel" %>
     85     {        
     86         <% foreach (ColumnSchema column in SourceTable.Columns) {%>
     87         <%if(new string[]{"IsDeleted"}.Contains(column.Name)){continue;} %>
     88         /// <summary>
     89         /// <%=column.Description %>
     90         /// </summary>
     91         public <%=GetCSharpVariableType(column)=="Guid" || GetCSharpVariableType(column)=="DateTime"?"string":GetCSharpVariableType(column) %> <%=GetPascalName(column) %> { get; set; }
     92         
     93         <% }%>
     94     }
     95     <%} %>
     96 }
     97 <script runat="template">
     98  
     99 public string MakeSingle(string name)
    100 {
    101     return name;
    102 }
    103 public string GetCamelName(ColumnSchema column)
    104 {
    105     return column.Name.Substring(0, 1).ToLower() + column.Name.Substring(1);
    106 }
    107 public string GetCamelName(string value)
    108 {
    109     return value.Substring(0, 1).ToLower() + value.Substring(1);
    110 }
    111 public string GetPascalName(ColumnSchema column)
    112 {
    113     return column.Name.Substring(0, 1).ToUpper() + column.Name.Substring(1);
    114 }
    115 public string GetPascalName(string value)
    116 {
    117     return value.Substring(0, 1).ToUpper() + value.Substring(1);
    118 }
    119 public string GetClassName(TableSchema table)
    120 {
    121     return GetPascalName(MakeSingle(table.Name));
    122 }    
    123 public string GetForeignKeyColumnType(ColumnSchema column)
    124 {        
    125     return column.Table.ForeignKeys[0].PrimaryKeyTable.Name;
    126 }
    127 public string GetForeignKeyColumnName(ColumnSchema column)
    128 {    
    129     if(column.Name.Substring(column.Name.Length-2).ToLower() == "id")
    130     {
    131         return column.Name.Substring(0,column.Name.Length-2);
    132     }
    133     else
    134     {
    135         return column.Name;
    136     }
    137 }
    138 public string GetPrimaryKeyType(TableSchema table)
    139 {
    140     if (table.PrimaryKey != null)
    141     {
    142         if (table.PrimaryKey.MemberColumns.Count == 1)
    143         {
    144             return GetCSharpVariableType(table.PrimaryKey.MemberColumns[0]);
    145         }
    146         else
    147         {
    148             throw new ApplicationException("This template will not work on primary keys with more than one member column.");
    149         }
    150     }
    151     else
    152     {
    153         throw new ApplicationException("This template will only work on tables with a primary key.");
    154     }
    155 }
    156 public string GetCSharpVariableType(ColumnSchema column)
    157 {
    158     if (column.Name.EndsWith("TypeCode")) return column.Name;
    159     
    160     switch (column.DataType)
    161     {
    162         case DbType.AnsiString: return "string";
    163         case DbType.AnsiStringFixedLength: return "string";
    164         case DbType.Binary: return "byte[]";
    165         case DbType.Boolean: return "bool";
    166         case DbType.Byte: return "byte";
    167         case DbType.Currency: return "decimal";
    168         case DbType.Date: return "DateTime";
    169         case DbType.DateTime: return "DateTime";
    170         case DbType.Decimal: return "decimal";
    171         case DbType.Double: return "double";
    172         case DbType.Guid: return "Guid";
    173         case DbType.Int16: return "short";
    174         case DbType.Int32: return "int";
    175         case DbType.Int64: return "long";
    176         case DbType.Object: return "object";
    177         case DbType.SByte: return "sbyte";
    178         case DbType.Single: return "float";
    179         case DbType.String: return "string";
    180         case DbType.StringFixedLength: return "string";
    181         case DbType.Time: return "TimeSpan";
    182         case DbType.UInt16: return "ushort";
    183         case DbType.UInt32: return "uint";
    184         case DbType.UInt64: return "ulong";
    185         case DbType.VarNumeric: return "decimal";
    186         default:
    187         {
    188             return "__UNKNOWN__" + column.NativeType;
    189         }
    190     }
    191 }    
    192 </script>
    View Code

     CodeSmith虽然方便,但是要安装和激活,这个是很麻烦的;而且每次生成都要打开CodeSmith去生成,不是很方便;

        于是我就照着原先在CodeSmith上模板写了个控制台应用程序,可以改写配合着bat使用,贼方便

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Data;
      4 using System.Data.SqlClient;
      5 using System.Text;
      6 using System.Linq;
      7 using System.IO;
      8 
      9 namespace Blog.Core.Test
     10 {
     11     public class Program
     12     {
     13         /// <summary>
     14         /// 数据库连接字符串
     15         /// </summary>
     16         private static string _connstr = "Data Source=localhost;Initial Catalog=Test;User Id=sa;Password=123456";
     17 
     18         /// <summary>
     19         /// 主函数
     20         /// </summary>
     21         /// <param name="args"></param>
     22         static void Main(string[] args)
     23         {
     24             Console.Write("命名空间:");
     25             string namespaces = Console.ReadLine();
     26             Console.Write("文件名:");
     27             string filename = Console.ReadLine();
     28             Console.WriteLine("开始生成,请等待...");
     29             new Program().Generate(namespaces, filename);
     30             Console.WriteLine("生成成功...");
     31             Console.ReadKey();
     32         }
     33 
     34         /// <summary>
     35         /// 生成Model文件
     36         /// </summary>
     37         /// <param name="namespaces"></param>
     38         /// <param name="filename"></param>
     39         private void Generate(string namespaces, string filename)
     40         {
     41             byte[] myByte = Encoding.UTF8.GetBytes(BuildTemplete(namespaces));
     42             string filepath = Environment.CurrentDirectory + "\" + filename;
     43             if (File.Exists(filepath))
     44             {
     45                 File.Delete(filepath);
     46             }
     47             using (FileStream fsWrite = new FileStream(filepath, FileMode.Append))
     48             {
     49                 fsWrite.Write(myByte, 0, myByte.Length);
     50             };
     51         }
     52 
     53         /// <summary>
     54         /// 创建模板
     55         /// </summary>
     56         /// <param name="namespaces"></param>
     57         /// <returns></returns>
     58         private string BuildTemplete(string namespaces)
     59         {
     60             StringBuilder templete = new StringBuilder("using System;");
     61             templete.Append("using System.Collections.Generic;
    
    ");
     62             templete.AppendFormat("namespace {0}
    {{
    ", namespaces);
     63             List<TableModel> tables = GetTables();
     64             foreach (var table in tables)
     65             {
     66                 templete.AppendFormat("    #region {0}
    ", table.name);
     67                 templete.Append("    /// <summary>
    ");
     68                 templete.AppendFormat("    /// {0}模型
    ", table.name);
     69                 templete.Append("    /// </summary>
    ");
     70                 templete.Append("    [Serializable]
    ");
     71                 templete.AppendFormat("    public class {0} : BaseModel
        {{", table.name);
     72                 templete.Append("
    ");
     73                 templete.Append("        /// <summary>
    ");
     74                 templete.Append("        /// 表名
    ");
     75                 templete.Append("        /// </summary>
    ");
     76                 templete.AppendFormat("        public static readonly string TableName = "{0}";
    ", table.name);
     77                 templete.Append("
    ");
     78                 templete.Append("        /// <summary>
    ");
     79                 templete.Append("        /// 构造函数
    ");
     80                 templete.Append("        /// </summary>
    ");
     81                 templete.AppendFormat("        public {0}() : base(TableName) {{ }}
    ", table.name);
     82                 templete.Append("        private Guid Id = Guid.Empty;
    ");
     83                 table.columns.ForEach(columu =>
     84                 {
     85                     templete.Append("
    ");
     86                     templete.Append("        /// <summary>
    ");
     87                     templete.AppendFormat("        /// {0}
    ", columu.ColComment);
     88                     templete.Append("        /// </summary>
    ");
     89                     if (columu.IsPk)
     90                     {
     91                         templete.AppendFormat("        public Guid {0}
    ", columu.ColName);
     92                         templete.Append("        {
    ");
     93                         templete.Append("            get { return Id; }
    ");
     94                         templete.Append("            set
    ");
     95                         templete.Append("            {
    ");
     96                         templete.Append("                Id = value;
    ");
     97                         templete.Append("                if (value != null)
    ");
     98                         templete.Append("                {
    ");
     99                         templete.Append("                    base.BaseId = value;
    ");
    100                         templete.Append("                }
    ");
    101                         templete.Append("            }
    ");
    102                         templete.Append("        }
    ");
    103                     }
    104                     else
    105                     {
    106                         templete.AppendFormat("        public {0} {1} {{ get; set; }} {2}
    ", GetCSType(columu.ColType), columu.ColName, GetCSDefault(columu.ColDefault));
    107                     }
    108                 });
    109                 templete.Append("    }");
    110 
    111                 templete.Append("
    ");
    112 
    113                 templete.Append("    /// <summary>
    ");
    114                 templete.AppendFormat("    /// {0}数据模型
    ", table.name);
    115                 templete.Append("    /// </summary>
    ");
    116                 templete.Append("    [Serializable]
    ");
    117                 templete.AppendFormat("    public class {0}ListData
        {{", table.name);
    118                 templete.Append("
    ");
    119                 templete.Append("        /// <summary>
    ");
    120                 templete.Append("        /// 总记录数
    ");
    121                 templete.Append("        /// </summary>
    ");
    122                 templete.Append("        public int RecordCount { get; set; }
    ");
    123                 templete.Append("        /// <summary>
    ");
    124                 templete.Append("
    ");
    125                 templete.Append("        /// 数据列表
    ");
    126                 templete.Append("        /// </summary>
    ");
    127                 templete.AppendFormat("        public List<{0}ListModel> RecordList {{ get; set; }}
    ", table.name);
    128                 templete.Append("    }");
    129 
    130                 templete.Append("
    ");
    131 
    132                 templete.Append("    /// <summary>
    ");
    133                 templete.AppendFormat("    /// {0}列表模型
    ", table.name);
    134                 templete.Append("    /// </summary>
    ");
    135                 templete.Append("    [Serializable]
    ");
    136                 templete.AppendFormat("    public class {0}ListModel
        {{", table.name);
    137                 templete.Append("
    ");
    138                 table.columns.ForEach(columu =>
    139                 {
    140                     if (columu.ColName != "IsDeleted")
    141                     {
    142                         templete.Append("
    ");
    143                         templete.Append("        /// <summary>
    ");
    144                         templete.AppendFormat("        /// {0}
    ", columu.ColComment);
    145                         templete.Append("        /// </summary>
    ");
    146                         if (new string[] { "Guid", "DateTime" }.Contains(GetCSType(columu.ColType)))
    147                         {
    148                             templete.AppendFormat("        public string {0} {{ get; set; }}
    ", columu.ColName);
    149                         }
    150                         else
    151                         {
    152                             templete.AppendFormat("        public {0} {1} {{ get; set; }}
    ", GetCSType(columu.ColType), columu.ColName);
    153                         }
    154                     }
    155                 });
    156                 templete.Append("    }
    ");
    157                 templete.Append("    #endregion
    ");
    158                 templete.Append("
    ");
    159             }
    160             templete = templete.Remove(templete.Length - 2, 1);
    161             templete.Append("}");
    162             return templete.ToString();
    163         }
    164 
    165         /// <summary>
    166         /// 获取表数据
    167         /// </summary>
    168         /// <returns></returns>
    169         private List<TableModel> GetTables()
    170         {
    171             List<TableModel> tables = new List<TableModel>();
    172             DataTable tabName = Query("SELECT name AS TableName FROM sysobjects WHERE xtype = 'U'");
    173             DataTable colName = Query(@"--获取表名、字段名称、字段类型、字段说明、字段默认值
    174                                         SELECT obj.name  AS TableName,--表名
    175                                                col.name  AS ColName,--列名
    176                                                typ.name  AS ColType,--字段类型
    177                                                cmt.value AS ColComment,--字段说明
    178                                                dft.text  AS ColDefault--字段默认值
    179                                         FROM   syscolumns col--字段
    180                                                INNER JOIN sysobjects obj--表
    181                                                        ON col.id = obj.id
    182                                                           AND obj.xtype = 'U'--表示用户表
    183                                                LEFT JOIN systypes typ--类型
    184                                                       ON col.xtype = typ.xusertype
    185                                                LEFT JOIN sys.extended_properties cmt--字段说明
    186                                                       ON col.id = cmt.major_id--表Id
    187                                                          AND col.colid = cmt.minor_id--字段Id
    188                                                LEFT JOIN syscomments dft--默认值
    189                                                       ON col.cdefault = dft.id
    190                                         ORDER  BY obj.name,
    191                                                   col.id ASC 
    192                                         ");
    193             DataTable pk = Query(@"--获取表的主键字段名
    194                                    SELECT CCU.COLUMN_NAME,
    195                                           TC.TABLE_NAME
    196                                    FROM   INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
    197                                           INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU
    198                                                   ON TC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME
    199                                    WHERE  TC.CONSTRAINT_TYPE = 'PRIMARY KEY' 
    200                                    ");
    201             foreach (DataRow row in tabName.Rows)
    202             {
    203                 TableModel table = new TableModel();
    204                 table.name = row["TableName"].ToString(); ;
    205                 table.columns = new List<ColumnModel>();
    206                 DataRow[] cols = colName.Select(string.Format("TableName = '{0}'", row["TableName"].ToString()));
    207                 DataRow[] pks = pk.Select(string.Format("TABLE_NAME = '{0}'", row["TableName"].ToString()));
    208                 string primarykey = pks == null || pks.Length == 0 ? "" : pks[0]["COLUMN_NAME"].ToString();
    209                 foreach (DataRow col in cols)
    210                 {
    211                     ColumnModel column = new ColumnModel();
    212                     column.IsPk = primarykey == col["ColName"].ToString();
    213                     column.ColName = col["ColName"].ToString();
    214                     column.ColType = col["ColType"].ToString();
    215                     column.ColComment = col["ColComment"].ToString();
    216                     column.ColDefault = col["ColDefault"].ToString();
    217                     table.columns.Add(column);
    218                 }
    219                 tables.Add(table);
    220             }
    221             return tables;
    222 
    223         }
    224 
    225         /// <summary>
    226         /// 简单的SQL查询
    227         /// </summary>
    228         /// <param name="sqlString"></param>
    229         /// <returns></returns>
    230         private DataTable Query(string sqlString)
    231         {
    232             DataTable dt = new DataTable();
    233             using (SqlConnection conn = new SqlConnection(_connstr))
    234             {
    235                 using (SqlCommand command = conn.CreateCommand())
    236                 {
    237                     command.CommandText = sqlString;
    238                     SqlDataAdapter adapter = new SqlDataAdapter();
    239                     adapter.SelectCommand = command;
    240                     adapter.Fill(dt);
    241                 }
    242             }
    243             return dt;
    244         }
    245 
    246         /// <summary>
    247         /// 获取C#类型
    248         /// </summary>
    249         /// <param name="sqlType"></param>
    250         /// <returns></returns>
    251         private string GetCSType(string sqlType)
    252         {
    253             switch (sqlType)
    254             {
    255                 case "datetime":
    256                     return "DateTime";
    257                 case "int":
    258                     return "int";
    259                 case "nchar":
    260                     return "string";
    261                 case "nvarchar":
    262                     return "string";
    263                 case "varchar":
    264                     return "string";
    265                 case "text":
    266                     return "string";
    267                 case "ntext":
    268                     return "string";
    269                 case "uniqueidentifier":
    270                     return "Guid";
    271                 case "decimal":
    272                     return "decimal";
    273                 case "float":
    274                     return "float";
    275                 case "bit":
    276                     return "byte";
    277                 case "binary":
    278                     return "byte []";
    279                 case "varbinary":
    280                     return "byte []";
    281                 case "timestamp":
    282                     return "int";
    283                 default:
    284                     return "";
    285             }
    286         }
    287 
    288         /// <summary>
    289         /// 获取C#默认值
    290         /// </summary>
    291         /// <param name="sqlValue"></param>
    292         /// <returns></returns>
    293         private string GetCSDefault(string sqlValue)
    294         {
    295             switch (sqlValue)
    296             {
    297                 case "((0))":
    298                     return "= 0;";
    299                 case "('')":
    300                     return "= string.Empty;";
    301                 case "('00000000-0000-0000-0000-000000000000')":
    302                     return "= Guid.Empty;";
    303                 default:
    304                     return "";
    305             }
    306         }
    307     }
    308 
    309     /// <summary>
    310     /// 表模型
    311     /// </summary>
    312     public class TableModel
    313     {
    314         /// <summary>
    315         /// 表名
    316         /// </summary>
    317         public string name { get; set; }
    318 
    319         /// <summary>
    320         /// 表字段
    321         /// </summary>
    322         public List<ColumnModel> columns { get; set; }
    323     }
    324 
    325     /// <summary>
    326     /// 字段模型
    327     /// </summary>
    328     public class ColumnModel
    329     {
    330         /// <summary>
    331         /// 是否主键
    332         /// </summary>
    333         public bool IsPk { get; set; }
    334 
    335         /// <summary>
    336         /// 列名
    337         /// </summary>
    338         public string ColName { get; set; }
    339 
    340         /// <summary>
    341         /// 列类型
    342         /// </summary>
    343         public string ColType { get; set; }
    344 
    345         /// <summary>
    346         /// 列说明
    347         /// </summary>
    348         public string ColComment { get; set; }
    349 
    350         /// <summary>
    351         /// 列默认值
    352         /// </summary>
    353         public string ColDefault { get; set; }
    354     }
    355 }
    View Code
    螃蟹在剥我的壳,笔记本在写我。 漫天的我落在枫叶雪花上。 而你在想我。
  • 相关阅读:
    字符串
    决策树
    结构体实验
    指针实验
    打印杨辉三角
    P176 1.2.3
    第七次作业
    第六次作业
    第五次作业
    第四次修改
  • 原文地址:https://www.cnblogs.com/skytitan/p/10138683.html
Copyright © 2020-2023  润新知