参考自这位大狮的:  https://github.com/Pencroff/Dapper-DAL/blob/master/Dapper-DAL/Models/ModelGenerator.tt

项目Demo下载 http://download.csdn.net/detail/qq_21533697/9904071

  • 支持Oracle,MSSQL,SQLite
  • Demo项目是个抽奖小程序,抽奖只用到了LuckDraw表
  • Demo用的SQLite包含库方便直接运行
  • 里面用到Dapper就只写了Model层的模板,

文件目录


T4库

表结构读取抽象类  SchemaReader.ttinclude

  1. <#+
  2. /*
  3. The contents of this file are subject to the New BSD
  4. License (the "License"); you may not use this file
  5. except in compliance with the License. You may obtain a copy of
  6. the License at http://www.opensource.org/licenses/bsd-license.php
  7.  
  8. Software distributed under the License is distributed on an
  9. "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10. implied. See the License for the specific language governing
  11. rights and limitations under the License.
  12. */
  13.  
  14. string ConnectionString = "";
  15. string TableFilter = "";
  16. string TopNamespace = "";
  17. string Namespace = "";
  18. string ClassPrefix = "";
  19. string ClassSuffix = "";
  20. string SchemaName = null;
  21. bool IncludeViews;
  22. string[] ExcludeTablePrefixes = new string[]{};
  23. string _connectionString="";
  24. string _providerName="";
  25.  
  26. static Regex rxCleanUp = new Regex(@"[^\w\d_]", RegexOptions.Compiled);
  27.  
  28. static Func<string, string> CleanUp = (str) =>
  29. {
  30. str = rxCleanUp.Replace(str, "_");
  31. if (char.IsDigit(str[])) str = "_" + str;
  32.  
  33. return str;
  34. };
  35.  
  36. string CheckNullable(Column col)
  37. {
  38. string result="";
  39. if(col.IsNullable &&
  40. col.PropertyType !="byte[]" &&
  41. col.PropertyType !="string" &&
  42. col.PropertyType !="Microsoft.SqlServer.Types.SqlGeography" &&
  43. col.PropertyType !="Microsoft.SqlServer.Types.SqlGeometry"
  44. )
  45. result="?";
  46. return result;
  47. }
  48.  
  49. static bool IsExcluded(string tablename, string[] ExcludeTablePrefixes)
  50. {
  51. for (int i = ; i < ExcludeTablePrefixes.Length; i++)
  52. {
  53. string s = ExcludeTablePrefixes[i];
  54. if(tablename.StartsWith(s)) return true;
  55. }
  56. return false;
  57. }
  58.  
  59. abstract class SchemaReader
  60. {
  61. public abstract Tables ReadSchema(string connstr, string tableFilter);
  62. public GeneratedTextTransformation outer;
  63. public void WriteLine(string o)
  64. {
  65. outer.WriteLine(o);
  66. }
  67.  
  68. public string GetPropertyType(string sqlType)
  69. {
  70. string sysType = "string";
  71. switch (sqlType)
  72. {
  73. case "bigint":
  74. sysType = "long";
  75. break;
  76. case "smallint":
  77. sysType = "short";
  78. break;
  79. case "int":
  80. case "number":
  81. case "integer":
  82. sysType = "int";
  83. break;
  84. case "uniqueidentifier":
  85. sysType = "Guid";
  86. break;
  87. case "smalldatetime":
  88. case "datetime":
  89. case "date":
  90. case "time":
  91. sysType = "DateTime";
  92. break;
  93. case "float":
  94. sysType = "double";
  95. break;
  96. case "real":
  97. sysType = "float";
  98. break;
  99. case "numeric":
  100. case "smallmoney":
  101. case "decimal":
  102. case "money":
  103. sysType = "decimal";
  104. break;
  105. case "tinyint":
  106. sysType = "byte";
  107. break;
  108. case "bit":
  109. sysType = "bool";
  110. break;
  111. case "image":
  112. case "binary":
  113. case "varbinary":
  114. case "timestamp":
  115. sysType = "byte[]";
  116. break;
  117. case "geography":
  118. sysType = "Microsoft.SqlServer.Types.SqlGeography";
  119. break;
  120. case "geometry":
  121. sysType = "Microsoft.SqlServer.Types.SqlGeometry";
  122. break;
  123. }
  124. return sysType;
  125. }
  126. }
  127.  
  128. public class Table
  129. {
  130. public List<Column> Columns;
  131. public string Name;
  132. public string Schema;
  133. public bool IsView;
  134. public string CleanName;
  135. public string ClassName;
  136. public string SequenceName;
  137. public bool Ignore;
  138.  
  139. public Column PK
  140. {
  141. get
  142. {
  143. return this.Columns.SingleOrDefault(x=>x.IsPK);
  144. }
  145. }
  146.  
  147. public Column GetColumn(string columnName)
  148. {
  149. return Columns.Single(x=>string.Compare(x.Name, columnName, true)==);
  150. }
  151.  
  152. public Column this[string columnName]
  153. {
  154. get
  155. {
  156. return GetColumn(columnName);
  157. }
  158. }
  159.  
  160. }
  161.  
  162. public class Column
  163. {
  164. public string Name;
  165. public string PropertyName;
  166. public string PropertyType;
  167. public string DbType;
  168. public bool IsPK;
  169. public bool IsNullable;
  170. public bool IsAutoIncrement;
  171. public bool Ignore;
  172. }
  173.  
  174. public class Tables : List<Table>
  175. {
  176. public Tables()
  177. {
  178. }
  179.  
  180. public Table GetTable(string tableName)
  181. {
  182. return this.Single(x=>string.Compare(x.Name, tableName, true)==);
  183. }
  184.  
  185. public Table this[string tableName]
  186. {
  187. get
  188. {
  189. return GetTable(tableName);
  190. }
  191. }
  192.  
  193. }
  194.  
  195. #>

SQLite表结构读取实现 SQLiteSchemaReader.ttinclude

  1. <#@ include file=".\SchemaReader.ttinclude" #>
  2. <#+
  3. Tables LoadTables()
  4. {
  5.  
  6. WriteLine("// This file was automatically generated by the Dapper.SimpleCRUD T4 Template");
  7. WriteLine("// Do not make changes directly to this file - edit the template instead");
  8. WriteLine("// ");
  9. WriteLine("// The following connection settings were used to generate this file");
  10. WriteLine("// ");
  11. WriteLine("// Connection String : `{0}`", ConnectionString);
  12. WriteLine("");
  13.  
  14. //DbProviderFactory _factory ;
  15. try
  16. {
  17. // _factory = DbProviderFactories.GetFactory(ProviderName);
  18. }
  19. catch (Exception x)
  20. {
  21. var error=x.Message.Replace("\r\n", "\n").Replace("\n", " ");
  22. WriteLine("");
  23. WriteLine("// -----------------------------------------------------------------------------------------");
  24. WriteLine("// -----------------------------------------------------------------------------------------");
  25. WriteLine("");
  26. return new Tables();
  27. }
  28.  
  29. try
  30. {
  31. Tables result;
  32.  
  33. SchemaReader reader= new SqliteSchemaReader();
  34. result=reader.ReadSchema(ConnectionString, TableFilter);
  35.  
  36. for (int i=result.Count-; i>=; i--)
  37. {
  38. if (SchemaName!=null && string.Compare(result[i].Schema, SchemaName, true)!=)
  39. {
  40. result.RemoveAt(i);
  41. continue;
  42. }
  43. if (!IncludeViews && result[i].IsView)
  44. {
  45. result.RemoveAt(i);
  46. continue;
  47. }
  48. }
  49.  
  50. var rxClean = new Regex("^(Equals|GetHashCode|GetType|ToString|repo|Save|IsNew|Insert|Update|Delete|Exists|SingleOrDefault|Single|First|FirstOrDefault|Fetch|Page|Query)$");
  51. foreach (var t in result)
  52. {
  53. t.ClassName = ClassPrefix + t.ClassName + ClassSuffix;
  54. foreach (var c in t.Columns)
  55. {
  56. c.PropertyName = rxClean.Replace(c.PropertyName, "_$1");
  57.  
  58. // Make sure property name doesn't clash with class name
  59. if (c.PropertyName == t.ClassName)
  60. c.PropertyName = "_" + c.PropertyName;
  61. }
  62. }
  63.  
  64. return result;
  65. }
  66. catch (Exception x)
  67. {
  68. var error=x.Message.Replace("\r\n", "\n").Replace("\n", " ");
  69. Warning(string.Format("Failed to read database schema - {0}", error));
  70. WriteLine("");
  71. WriteLine("// -----------------------------------------------------------------------------------------");
  72. WriteLine("// Failed to read database schema - {0}", error);
  73. WriteLine("// -----------------------------------------------------------------------------------------");
  74. WriteLine("");
  75. return new Tables();
  76. }
  77.  
  78. }
  79.  
  80. class SqliteSchemaReader : SchemaReader
  81. {
  82.  
  83. private string _connstr {get;set;}
  84.  
  85. public override Tables ReadSchema(string connstr, string tableFilter)
  86. {
  87. _connstr = connstr;
  88. var result = new Tables();
  89. //pull the tables in a reader
  90. using (IDataReader rdr = ExecuteReader(TABLE_SQL + tableFilter)) // SQLitehelper.
  91. {
  92. while (rdr.Read())
  93. {
  94. Table tbl = new Table();
  95. tbl.Name = rdr["name"].ToString();
  96. //tbl.Schema = rdr["TABLE_SCHEMA"].ToString();
  97. //tbl.IsView = string.Compare(rdr["TABLE_TYPE"].ToString(), "View", true) == 0;
  98. tbl.CleanName = CleanUp(tbl.Name);
  99. // tbl.CleanName = T4Generator.CleanUp(tbl.Name);
  100. if (tbl.CleanName.StartsWith("tbl_")) tbl.CleanName = tbl.CleanName.Replace("tbl_", "");
  101. if (tbl.CleanName.StartsWith("tbl")) tbl.CleanName = tbl.CleanName.Replace("tbl", "");
  102. tbl.CleanName = tbl.CleanName.Replace("_", "");
  103. tbl.ClassName = tbl.CleanName;
  104.  
  105. result.Add(tbl);
  106. }
  107. }
  108.  
  109. foreach (var tbl in result)
  110. {
  111. tbl.Columns = LoadColumns(tbl);
  112.  
  113. //Mark the primary key
  114. //string PrimaryKey = GetPK(tbl.Schema, tbl.Name);
  115. //var pkColumn = tbl.Columns.SingleOrDefault(x => x.Name.ToLower().Trim() == PrimaryKey.ToLower().Trim());
  116. //if (pkColumn != null)
  117. //{
  118. // pkColumn.IsPK = true;
  119. //}
  120. }
  121.  
  122. return result;
  123. }
  124.  
  125. List<Column> LoadColumns(Table tbl)
  126. {
  127. var result = new List<Column>();
  128. using (IDataReader rdr = ExecuteReader(COLUMN_SQL.Replace("@tableName", tbl.Name))) // SQLitehelper.
  129. {
  130. while (rdr.Read())
  131. {
  132. Column col = new Column();
  133. col.Name = rdr["name"].ToString();
  134. col.PropertyName = CleanUp(col.Name);
  135. //col.PropertyName = T4Generator.CleanUp(col.Name);
  136. col.PropertyType = base.GetPropertyType(rdr["type"].ToString().ToLower());
  137. col.IsNullable = rdr["notnull"].ToString() != "";
  138. //col.IsAutoIncrement = false; //((int)rdr["IsIdentity"]) == 1;
  139. col.IsPK = rdr["pk"].ToString() == "";
  140. result.Add(col);
  141. }
  142. }
  143.  
  144. return result;
  145. }
  146.  
  147. string Table_Filter = " ";
  148.  
  149. const string TABLE_SQL = " select name from sqlite_master where type = 'table' ";
  150.  
  151. const string COLUMN_SQL = " PRAGMA table_info(@tableName) ";
  152.  
  153. /// <summary>
  154. /// 查询
  155. /// </summary>
  156. /// <param name="sql">sql语句</param>
  157. /// <param name="slPars">参数</param>
  158. /// <returns>发挥SQLiteDataReader</returns>
  159. public SQLiteDataReader ExecuteReader(string sql, params SQLiteParameter[] slPars)
  160. {
  161. SQLiteConnection conn = new SQLiteConnection(_connstr);
  162. using (SQLiteCommand cmd = new SQLiteCommand(sql,conn))
  163. {
  164. if (slPars != null)
  165. {
  166. cmd.Parameters.AddRange(slPars);
  167. }
  168. try
  169. {
  170. conn.Open();
  171. return cmd.ExecuteReader(CommandBehavior.CloseConnection);
  172. }
  173. catch(Exception ex)
  174. {
  175. conn.Close();
  176. conn.Dispose();
  177. throw ex;
  178. }
  179.  
  180. }
  181.  
  182. }
  183.  
  184. }
  185. #>

SQLite配置文件  SQLiteInit.ttinclude

1.配置连接串  注意修改连接串为自己对应的  ConnectionString = @"Data Source=E:/cc/test/LotterySite/Lib/db/cater.db;";

2.需要生成的表  3.顶级命名空间   4.一个库对应一个配置文件  (开始是把这些配置直接写在各层模板文件的,后来涉及多库的切换,每个文件改链接麻烦)

  1. <#@ include file="./SQLiteSchemaReader.ttinclude" #>
  2. <# // 初始化文件 一个库对应一个ttinclude文件
  3. // Settings 初始化配置
  4. ConnectionString = @"Data Source=E:/cc/test/LotterySite/Lib/db/cater.db;"; // 连接串
  5. TableFilter = " and name in ('LuckDraw') "; // 过滤表
  6. TopNamespace = "FW"; // 顶级命名空间
  7. ClassPrefix = "";
  8. ClassSuffix = "";
  9. IncludeViews = true;
  10. ExcludeTablePrefixes = new string[]{"aspnet_","webpages_"};
  11.  
  12. // Read schema
  13. var tables = LoadTables(); //读取的所有表结构
  14. #>

SQLite 模板使用 

  1. <#@ template hostspecific="True" #>
  2. <#@ include file="EF.Utility.CS.ttinclude"#>
  3. <#@ include file="$(SolutionDir)\FW.Common\T4Ttinclude\SQLiteInit.ttinclude" #>
  4. <#@ assembly name="EnvDTE" #>
  5. <#@ assembly name="System.Data" #>
  6. <#@ assembly name="System.Data.Entity.Design" #>
  7. <#@ assembly name="System.Xml" #>
  8. <#@ assembly name="System.Configuration" #>
  9. <#@ assembly name="$(SolutionDir)\Lib\sqlite\System.Data.SQLite.dll" #>
  10.  
  11. <#@ import namespace="System.Collections.Generic" #>
  12. <#@ import namespace="System.Data" #>
  13. <#@ import namespace="System.Data.Common" #>
  14. <#@ import namespace="System.Diagnostics" #>
  15. <#@ import namespace="System.Globalization" #>
  16. <#@ import namespace="System.IO" #>
  17. <#@ import namespace="System.Linq" #>
  18. <#@ import namespace="System.Text" #>
  19. <#@ import namespace="System.Text.RegularExpressions" #>
  20. <#@ import namespace="System.Configuration" #>
  21. <#@ import namespace="System.Data.SQLite" #>
  22. <#@ output extension=".cst"#>
  23.  
  24. <#
  25. Namespace = TopNamespace + ".TestModel";
  26. // Read schema
  27.  
  28. EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); // 多文件生成
  29. /*
  30. // Tweak Schema
  31. tables["tablename"].Ignore = true; // To ignore a table
  32. tables["tablename"].ClassName = "newname"; // To change the class name of a table
  33. tables["tablename"]["columnname"].Ignore = true; // To ignore a column
  34. tables["tablename"]["columnname"].PropertyName="newname"; // To change the property name of a column
  35. tables["tablename"]["columnname"].PropertyType="bool"; // To change the property type of a column
  36. */
  37. #>
  38.  
  39. <# fileManager.StartHeader(); #>
  40.  
  41. using System;
  42. using Dapper;
  43. using Dapper.Contrib.Extensions;
  44.  
  45. namespace <#=Namespace #>
  46. {
  47.  
  48. <# fileManager.EndBlock(); #>
  49.  
  50. <#
  51. foreach(Table tbl in from t in tables where !t.Ignore select t){
  52. if(IsExcluded(tbl.Name, ExcludeTablePrefixes)) continue;
  53.  
  54. fileManager.StartNewFile(tbl.Name+".cs"); // 新建文件
  55. #>
  56. /// <summary>
  57. /// A class which represents the <#=tbl.Name#> <#=(tbl.IsView)?"view":"table"#>.
  58. /// </summary>
  59. [Table("[<#=tbl.Name#>]")]
  60. public partial class <#=tbl.ClassName#>
  61. {
  62. /* <#foreach(Column col in from c in tbl.Columns where !c.Ignore select c) {#> <#=col.PropertyName #> <#}#> */
  63.  
  64. <#foreach(Column col in from c in tbl.Columns where !c.Ignore select c)
  65. {#>
  66. <# if (tbl.PK!=null && tbl.PK.Name==col.PropertyName) { #>
  67. [Key]
  68. <#}#>
  69. public virtual <#=col.PropertyType #><#=CheckNullable(col)#> <#=col.PropertyName #> { get; set; }
  70. <#}#>
  71. }
  72.  
  73. <#}#>
  74.  
  75. <# fileManager.StartFooter(); #>
  76. } // namespace
  77. <# fileManager.EndBlock(); #>
  78. <# fileManager.Process(true); #>

模板属性:

Namespace 命名空间
tables 表结构集合

表属性 
Name 数据库中的表名
ClassName 实体类名称
IsView 是否是视图(没怎么用)
PK.Name 主键列名

列属性
PropertyName 属性名称
PropertyType 属性类型
CheckNullable(col) 可空类型判断

注意引入对应的SQLite的T4配置库   

<#@ include file="$(SolutionDir)\FW.Common\T4Ttinclude\SQLiteInit.ttinclude" #>

$(SolutionDir)         解决方案目录

T4 代码生成 Demo (抽奖程序)的更多相关文章

  1. sql的行转列(PIVOT)与列转行(UNPIVOT) webapi 跨域问题 Dapper 链式查询 扩展 T4 代码生成 Demo (抽奖程序)

    sql的行转列(PIVOT)与列转行(UNPIVOT)   在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比 ...

  2. 使用jQuery+PHP+Mysql实现抽奖程序

    抽奖程序在实际生活中广泛运用,由于应用场景不同抽奖的方式也是多种多样的.本文将采用实例讲解如何利用jQuery+PHP+Mysql实现类似电视中常见的一个简单的抽奖程序. 查看演示 本例中的抽奖程序要 ...

  3. jQuery幸运大转盘_jQuery+PHP抽奖程序的简单实现

    jQuery幸运大转盘_jQuery+PHP抽奖程序的简单实现 在线实例 查看演示 完整代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...

  4. 一个好玩的jq+php实现转盘抽奖程序

    前台页面: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <met ...

  5. 幸运大转盘-jQuery+PHP实现的抽奖程序

    目前好多网站上应用的转盘抽奖程序大多是基于flash的,而本文结合实例将使用jQuery和PHP来实现转盘抽奖程序,为了便于理解,作者分两部分来讲解,本文讲解第一部分,侧重使用jQuery实现转盘的转 ...

  6. java模拟一个抽奖程序

    今天用一个程序模拟一个从1-32之间,随机抽取7组号码的抽奖程序 * 需要使用Java的图形界面知识 * 窗口  JFrame * 面板  JPanel * 显示文本信息的标签  JLabel * 文 ...

  7. jQuery幸运大转盘_jQuery+PHP抽奖程序

    http://www.thinkphp.cn/code/1153.html 网上转盘抽奖程序大多是flash完成的,而本文使用jQuery和PHP来实现转盘抽奖程序. 若是想看更多js特效.网站源码. ...

  8. .net+mssql制作抽奖程序思路及源码

    近期一直在研究数据库,刚好有个项目要做抽奖程序,恩,拿来练练手吧. 抽奖程序: 思路整理,无非就是点一个按钮,然后一个图片旋转一会就出来个结果就行了,可这个程序的要求不是这样的,是需要从数据库中随机抽 ...

  9. 简单的javascript抽奖程序

    <html>  <head>   <title>手机号码抽奖程序</title>   <script>    //声明一个数组装住号码,可根 ...

随机推荐

  1. [.NET跨平台]Jeuxs独立版本的便利与过程中的一些坑

    本文环境与前言 之前写过一篇相关的文章:在.NET Core之前,实现.Net跨平台之Mono+CentOS+Jexus初体验 当时的部署还是比较繁琐的,而且需要联网下载各种东西..有兴趣的可以看看, ...

  2. 01--数据库MySQL:【数据库DB】和【数据库管理系统DBMS】 简介

    1.数据库DB 数据库:DB(DataBase) 按照一定规则存储在计算机的内部存储设备上被各种用户或者应用共享的数据集合 2.数据库管理系统DBMS 1)数据库管理系统DBMS:DBMS(DataB ...

  3. 一天搞定CSS:表单(form)--20

    1.表单标签 2.input标签属性与取值 代码演示 <!DOCTYPE html> <html> <head> <meta charset="UT ...

  4. 可视化之AQICN

    上一篇和大家分享了<可视化之Berkeley Earth>,这次看一看下面这个网站---aqicn.org.先做一个提示:文末有惊喜~ 该网站在中国有一定的权威性,PM2.5数据有一点敏感 ...

  5. Android Studio的两种模式及签名配置

    我们使用Android Studio 运行我们的app,无非两种模式:debug和release模式. debug模式 debug模式使用一个默认的debug.keystore进行签名. 这个默认签名 ...

  6. 如何修改"DEDECMS 提示信息!"方法!

    dedecms程序使用过程中,经常有一些跳转提示信息会出现“DEDECMS 提示信息!”这几个字样. 很多朋友都想对他进行修改,改为自己网站的提示信息,其实方法也是很简单的,方法如下: 用编辑器打开i ...

  7. JavaScript数组知识点

    强类型语言数组特点:连续的,指定好长度, 还要规定好数据类型弱类型语言数组特点:不一定是连续的 可以不用指定长度 不限定数据类型(可以存储任意类型的数据)数组定义方式:1.var arr=new Ar ...

  8. PHP:win7 ASP.NET环境与PHP(WAMP)环境如何共存

    经验地址:http://jingyan.baidu.com/article/495ba8410f794d38b30ede89.html 笔记本以前安装过asp.net,启用了Windows的IIS服务 ...

  9. c++,函数名不要和某个类名相同 (syntax error : missing ';' before identifier....)

    直接上代码: // outside.h class Outside { private: class Inner { public: Inner(Outside& out) : out_(ou ...

  10. v9 调用模型中新增的字段

    在模型中新增字段的时候,可以选择“是否为主表”. 若选是,则前台调用可直接通过字段名调用. 若选否,在前台调用是应在{pc:content}中添加 moreinfo="1",表示允 ...