这是一个妥妥的NPoco类,这是我们在工作开发中,手动去写这个实体类,属实非常心累,字段少无所谓一次两次,数量多了,字段多了,就心态裂开


今天分享一下如何使用T4模板生成实体类

using System;
using NPoco;
using System.ComponentModel.DataAnnotations; namespace Electric.Domain.Entities
{
/// <summary>
/// Represents a T_RepairParts.
/// NOTE: 这个类是从T4模板生成的——你不应该手动修改它。
/// </summary>
[MetadataType(typeof(T_RepairPartsMetadata))]
[PrimaryKey("ID")]
[TableName("[dbo].[T_RepairParts]")]
public class T_RepairParts
{
#region ResultColumn
#endregion
#region Ignore
#endregion private class T_RepairPartsMetadata{ [StringLength(4, ErrorMessage = "{0}不能超过4个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "")]
[Column("ID")]
public int Id { get; set; } [StringLength(50, ErrorMessage = "{0}不能超过50个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "配件名称")]
[Column("PartsName")]
public string PartsName { get; set; } [StringLength(100, ErrorMessage = "{0}不能超过100个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "绑定品牌")]
[Column("RelationBrands")]
public string RelationBrands { get; set; } [StringLength(100, ErrorMessage = "{0}不能超过100个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "关联维修")]
[Column("RelationMaintainers")]
public string RelationMaintainers { get; set; } [StringLength(100, ErrorMessage = "{0}不能超过100个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "关联车系")]
[Column("RelationVehicleSeries")]
public string RelationVehicleSeries { get; set; } [StringLength(-1, ErrorMessage = "{0}不能超过-1个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "")]
[Column("EditorContent")]
public string EditorContent { get; set; } [StringLength(-1, ErrorMessage = "{0}不能超过-1个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "")]
[Column("BasicDetails")]
public string BasicDetails { get; set; } [StringLength(8, ErrorMessage = "{0}不能超过8个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "创建时间")]
[Column("CreateTime")]
public DateTime CreateTime { get; set; } [Display(Name = "修改时间")]
[Column("Updatetime")]
public DateTime? Updatetime { get; set; } [StringLength(1, ErrorMessage = "{0}不能超过1个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "是否删除")]
[Column("IsDel")]
public bool IsDel { get; set; } [StringLength(200, ErrorMessage = "{0}不能超过200个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "配件标签")]
[Column("Tips")]
public string Tips { get; set; } [StringLength(9, ErrorMessage = "{0}不能超过9个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "人工价")]
[Column("LaborPrice")]
public decimal LaborPrice { get; set; } [StringLength(9, ErrorMessage = "{0}不能超过9个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "配件价")]
[Column("PartsPrice")]
public decimal PartsPrice { get; set; } [StringLength(9, ErrorMessage = "{0}不能超过9个字符!")]
[Required(ErrorMessage = "请填写{0}!")]
[Display(Name = "门店市场价格")]
[Column("StorePrice")]
public decimal StorePrice { get; set; } }
}
}

模板是搬运国外一个大神博客内的代码,下面换个模板是我改后增强的
支持生成字段注释,支持生成字段可空,支持生成字段长度,我并且按照我自己的项目类结构重新弄了一下,原版的T4代码我也分享出来,可以看看

帮助文章: https://www.davidhaney.io/automatically-generate-pocos-from-db-with-t4/

我改后的-T4模板代码

<#@ template language="C#" hostspecific="true" debug="True" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #> <#@ assembly name="System.Xml" #>
<#@ assembly name="System.Configuration" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>
<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #> <#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="Microsoft.SqlServer.Management.Smo" #> <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Data.SqlClient" #>
<# var configurationFileMap = new ExeConfigurationFileMap();
configurationFileMap.ExeConfigFilename = this.Host.ResolvePath("App.config");
var config = ConfigurationManager.OpenMappedExeConfiguration(configurationFileMap, ConfigurationUserLevel.None); //**********************************************************************************************
// This T4 generates POCOs from the specified DB and saves them to the specified folder which
// is relative to the template's location. One file per table/POCO.
//**********************************************************************************************
//****************************
// DEFINE YOUR VARIABLES HERE
//****************************
// The SQL server name or IP
string sqlServer = config.AppSettings.Settings["sqlServer"].Value;
// The SQL username
string sqlLogin = config.AppSettings.Settings["sqlLogin"].Value;
// The SQL password
string sqlPassword = config.AppSettings.Settings["sqlPassword"].Value;
// The SQL database to generate the POCOs for
string sqlDatabase = config.AppSettings.Settings["sqlDatabase"].Value;
// The namespace to apply to the generated classes
string classNamespace = config.AppSettings.Settings["classNamespace"].Value;
// The destination folder for the generated classes, relative to this file's location.
string destinationFolder = config.AppSettings.Settings["destinationFolder"].Value;
// Loop over each table and create a class file!
Server server = new Server(sqlServer);
server.ConnectionContext.LoginSecure = false;
server.ConnectionContext.Login = sqlLogin;
server.ConnectionContext.Password = sqlPassword;
server.ConnectionContext.Connect();
foreach (Table table in server.Databases[sqlDatabase].Tables)
{
// Skip sys tables
if (table.Name.StartsWith("sys"))
{
continue;
} string nombreTabla="["+ table.Schema +"].["+table.Name+"]"; //search PK
String namePK="";
foreach (Column col in table.Columns)
{
if(col.InPrimaryKey){
namePK=col.Name;
continue;
}
} String nameSchema="";
if(!table.Schema.Equals("dbo")){
nameSchema = "."+table.Schema;
} #>
using System;
using NPoco;
using System.ComponentModel.DataAnnotations; namespace <#= classNamespace #><#= nameSchema #>
{
/// <summary>
/// Represents a <#= table.Name #>.
/// NOTE: 这个类是从T4模板生成的——你不应该手动修改它。
/// </summary>
[MetadataType(typeof(<#=table.Name + "Metadata"#>))]
[PrimaryKey("<#= namePK #>")]
[TableName("<#= nombreTabla #>")]
public class <#= table.Name #>
{
#region ResultColumn
#endregion
#region Ignore
#endregion private class <#=table.Name + "Metadata"#>{
<#
// Keep count so we don't whitespace the last property/column
int columnCount = table.Columns.Count;
int i = 0;
// Iterate all columns
foreach (Column col in table.Columns)
{
i++;
string propertyType = GetNetDataType(col.DataType.Name);
// If we can't map it, skip it
if (string.IsNullOrWhiteSpace(propertyType))
{
// Skip
continue;
}
string strLength = string.Empty;
string remark = GetRemark(col.Name,nombreTabla,config.AppSettings);
string strNullable = string.Empty;
// Handle nullable columns by making the type nullable
if (col.Nullable && propertyType != "string")
{
propertyType += "?";
}else{
strLength = "[StringLength(" + col.DataType.MaximumLength +", ErrorMessage = \"{0}不能超过"+col.DataType.MaximumLength+"个字符!\")]";
} if (!col.Nullable)
{
strNullable = "[Required(ErrorMessage = \"请填写{0}!\")]";
} String nameColumn="Id";
String nameColumnNPoco=col.Name; if(!col.InPrimaryKey){
nameColumn=FirstCharToUpper(col.Name);
}
#>
<#=strLength#>
<#=strNullable#>
[Display(Name = "<#=remark#>")]
[Column("<#= nameColumnNPoco #>")]
public <#= propertyType #> <#= nameColumn #> { get; set; } <#
// Do we insert the space?
if (i != columnCount)
{
#>
<#
}
#>
<#
}
#>
}
}
}
<#
// Write new POCO class to its own file
SaveOutput(table.Name + ".cs", destinationFolder);
}
#>
<#+
public static string GetNetDataType(string sqlDataTypeName)
{
switch (sqlDataTypeName.ToLower())
{
case "bigint":
return "Int64";
case "binary":
case "image":
case "varbinary":
return "byte[]";
case "bit":
return "bool";
case "char":
return "char";
case "datetime":
case "smalldatetime":
return "DateTime";
case "decimal":
case "money":
case "numeric":
return "decimal";
case "float":
return "double";
case "int":
return "int";
case "nchar":
case "nvarchar":
case "text":
case "varchar":
case "xml":
return "string";
case "real":
return "single";
case "smallint":
return "Int16";
case "tinyint":
return "byte";
case "uniqueidentifier":
return "Guid";
default:
return null;
}
} //码农disco修改版,支持字段注释
public static string GetRemark(string name,string table,AppSettingsSection config)
{
string result = string.Empty;
if (table == "[dbo].[T_RepairParts]" && name!="ID")
{ }
string sqlServer = config.Settings["sqlServer"].Value;
string sqlLogin = config.Settings["sqlLogin"].Value;
string sqlPassword = config.Settings["sqlPassword"].Value;
string sqlDatabase = config.Settings["sqlDatabase"].Value; string connString = "Server="+ sqlServer +";DataBase="+sqlDatabase+";Uid="+sqlLogin+";Pwd="+sqlPassword;
SqlConnection conn = new SqlConnection(connString); string sql = string.Format(@" USE electric2014
SELECT
A.name AS table_name,
B.name AS column_name,
C.value AS column_description
FROM sys.tables A
INNER JOIN sys.columns B ON B.object_id = A.object_id
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
WHERE A.name = '{0}' AND B.name = '{1}' ",table.Replace("dbo","").Replace("[","").Replace("]","").Replace(".",""),name);
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
result = dr["column_description"].ToString();
}
conn.Close();
return result;
} public static string FirstCharToUpper(string input)
{
if (String.IsNullOrEmpty(input))
throw new ArgumentException("ARGH!");
return input.First().ToString().ToUpper() + input.Substring(1);
} void SaveOutput(string outputFileName, string destinationFolder)
{
// Write to destination folder
string templateDirectory = Path.Combine(Path.GetDirectoryName(Host.TemplateFile), destinationFolder);
string outputFilePath = Path.Combine(templateDirectory, outputFileName);
File.Delete(outputFilePath);
File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
// Flush generation
this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length);
}
#>

所有表生成的类都会写到Export内,这下美滋滋了!

项目源代码下载:github
代码最好拉取Git上的,因为博客的这个代码,可能后面不会再更新了

使用T4模板动态生成NPoco实体类的更多相关文章

  1. 使用T4模板动态生成邮件内容并储存到任意位置

    一.基础概念介绍 T4模板是扩展名为 .tt 的文本文件. 他分为设计时模板 和运行时模板.主要区别在于在vs中右键点击文件,打开“属性”,在“自定义工具”一栏中的值分别如下: 设计时模板: Text ...

  2. 讨论一下hibernate如何动态注册一个动态生成的实体类

    如何动态生成实体类请参考这篇博文:http://www.cnblogs.com/anai/p/4269858.html 下面说说得到实体类后,如何能使用hibernate的接口来进行数据访问. 我们都 ...

  3. T4模版自动生成MSSQL实体类

    在Model层建立ModelAuto.ttinclude文件 <#@ assembly name="System.Core"#> <#@ assembly nam ...

  4. 使用T4模板同时生成多个类文件

    代码: <#@ template language="C#" debug="false" hostspecific="true"#&g ...

  5. T4 模板自动生成带注释的实体类文件

    T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll 生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 如果你没有 ...

  6. T4教程2 T4模版引擎之生成数据库实体类

    T4模版引擎之生成数据库实体类   在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中 ...

  7. PetaPoco T4模板修改生成实体

    PetaPoco T4 模板生成的实体类全部包含再一个.CS文件中.通过修改PetaPoco的T4模板,生成单文件实体. 1.生成单CS文件模板: SigleFile.ttinclude <#@ ...

  8. [转]T4模版引擎之生成数据库实体类

    本文转自:http://www.cnblogs.com/lzrabbit/archive/2012/07/18/2597953.html 在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实 ...

  9. T4模版引擎之生成数据库实体类

    在通过T4模版引擎之基础入门 对T4有了初步印象后,我们开始实战篇.T4模板引擎可以当做一个代码生成器,代码生成器的职责当然是用来生成代码(这不是废话吗).而这其中我们使用的最普遍的是根据数据库生成实 ...

随机推荐

  1. ERP的协议管理的操作与设计--开源软件诞生27

    赤龙ERP协议与订单进阶讲解--第27篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/re ...

  2. GC 的认识(转) https://github.com/qcrao/Go-Questions/blob/master/GC/GC.md#1-什么是-gc有什么作用

    1. 什么是 GC,有什么作用? GC,全称 Garbage Collection,即垃圾回收,是一种自动内存管理的机制. 当程序向操作系统申请的内存不再需要时,垃圾回收主动将其回收并供其他代码进行内 ...

  3. 美团面试官问我: ZGC 的 Z 是什么意思

    本文的阅读有一定的门槛,请先了解 GC 的基本只知识. 现代垃圾收集器的演进大部分都是往减少停顿方向发展. 像 CMS 就是分离出一些阶段使得应用线程可以和垃圾回收线程并发,当然还有利用回收线程的并行 ...

  4. centos7安装数据库 (系统包含预装环境mariadb)

    查看系统是否安装了MySQL,有些没安装但是有路径,那是因为系统安装了mariadb-libs,对应的配置文件目录:/etc/my.cnf(下面就根据mariadb来安装mysql) 查看系统预装ma ...

  5. 用JavaScript做精灵图

    用JavaScript做精灵图 精灵图可以不用在给每一个小块一 一的修改位置.主要原理是找到整张的背景图与li的下标的数学关系. 这是一大张背景图,这个背景图的位置其实是有规律的,每两张之间间隔一个固 ...

  6. Nginx下关于缓存控制字段cache-control的配置说明

    HTTP协议的Cache -Control指定请求和响应遵循的缓存机制.在请求消息或响应消息中设置 Cache-Control并不会影响另一个消息处理过程中的缓存处理过程.请求时的缓存指令包括: no ...

  7. 看阿里P7讲MyBatis:从MyBatis的理解以及配置和实现全帮你搞懂

    前言 MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL.存储过程以及高级映`射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结 ...

  8. FL Studio 插件使用教程 —— 3x Osc(上)

    在FL Studio20 中,3x Osc是继TS404插件之后资历最老的插件之一,也是FL Studio20 中最重要.使用率最高的插件之一.相比别的FL Studio20内置插件,3x Osc 相 ...

  9. FL studio系列教程(一):什么是FL水果音乐制作软件

    如今,越来越多的音乐人选择使用音乐制作软件来进行音乐的创作,一台电脑.一款软件以及一个外接MIDI就是一个小型的音乐工作站.FL Studio成了音乐界萌新的首选,目前最新的版本为FL Studio2 ...

  10. 接入twitter第三方登陆接口遇到的一个问题

    本地开了 Shadowsocks,然后postman模拟的twitter的接口是请求成功的,然后用php-curl去请求网址,出现以下错误 Failed to connect to api.twitt ...