将一些公用的东西弄到一个类库DM.T4里面,哪个项目需要用到t4生成的话,将DM.T4的生成事件中将dll和ModelAuto.ttinclude复制到需要使用T4的项目的生成目录下,如果这样
代码语言:javascript复制copy $(TargetPath) $(SolutionDir)DM.Domain$(OutDir)
copy $(TargetDir)ModelAuto.ttinclude $(SolutionDir)DM.Domain$(OutDir)
然后在需要就可以添加T4文件了,T4文件头部引入即可,例如下面的这个例子,就是根据表生成一些类
代码语言:javascript复制<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="$(TargetDir)DM.T4.dll"#>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.Text.RegularExpressions"#>
<#@ import namespace="DM.T4"#>
<#@ include file="$(TargetDir)ModelAuto.ttinclude"#>
<# var manager2 = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile)}; #>
<#
ModelManager manager = new ModelManager();
List<string> list=manager.GetTableList();
foreach (var item in list)
{
string tableName=item;
DataTable table= manager.GetTableSchema(tableName);
string strTableMemo=string.Empty;
if(table!=null&&table.Rows.Count>0)
{
strTableMemo=table.Rows[0]["表说明"].ToString();
}
manager2.StartBlock(tableName "Repository.cs");
#>
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码从T4模板生成。
// 黄正辉(623128629@qq.com)
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using System.Data.Common;
using DM.Domain;
using DM.Tools;
using DM.Interface;
using DM.Interface.IRepository;
namespace DM.Repository.BusinessRepository
{
/// <summary>
/// 仓储实现:<#= strTableMemo #> (<#= tableName #>)
/// </summary>
public partial class <#=tableName #>Repository :RepositoryBase<<#=tableName #>>, I<#=tableName #>Repository,IDependency
{
/// <summary>
/// 插入一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Insert(<#=tableName #> entity)
{
return base.Insert(entity);
}
/// <summary>
/// 插入一个数据列表
/// </summary>
/// <param name="entity">实体列表</param>
/// <returns>受影响行数</returns>
public virtual int Insert(List<<#=tableName #>> entitys)
{
return base.Insert(entitys);
}
/// <summary>
/// 修改一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Update(<#=tableName #> entity)
{
return base.Update(entity);
}
/// <summary>
/// 删除一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Delete(<#=tableName #> entity)
{
return base.Delete(entity);
}
/// <summary>
/// 根据表达式删除
/// </summary>
/// <param name="predicate">实体</param>
/// <returns>受影响行数</returns>
public virtual int Delete(Expression<Func<<#=tableName #>, bool>> predicate)
{
return base.Delete(predicate);
}
/// <summary>
/// 根据主键查询一个数据
/// </summary>
/// <param name="keyValue">主键值</param>
/// <returns>实体</returns>
public virtual <#=tableName #> FindEntity(object keyValue)
{
return base.FindEntity(keyValue);
}
/// <summary>
/// 根据表达式查询一个数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns>实体</returns>
public virtual <#=tableName #> FindEntity(Expression<Func<<#=tableName #>, bool>> predicate)
{
return base.FindEntity(predicate);
}
/// <summary>
/// 查询IQueryable列表
/// </summary>
/// <returns>IQueryable列表</returns>
public virtual IQueryable<<#=tableName #>> IQueryable()
{
return base.IQueryable();
}
/// <summary>
/// 根据表达式查询IQueryable列表数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns>IQueryable列表</returns>
public virtual IQueryable<<#=tableName #>> IQueryable(Expression<Func<<#=tableName #>, bool>> predicate)
{
return base.IQueryable(predicate);
}
/// <summary>
/// 根据Sql查询数据
/// </summary>
/// <param name="strSql">Sql</param>
/// <returns>数据列表</returns>
public virtual List<<#=tableName #>> FindList(string strSql)
{
return base.FindList(strSql);
}
/// <summary>
/// 根据Sql查询数据
/// </summary>
/// <param name="strSql">Sql</param>
/// <param name="dbParameter">参数列表</param>
/// <returns>数据列表</returns>
public virtual List<<#=tableName #>> FindList(string strSql, DbParameter[] dbParameter)
{
return base.FindList(strSql,dbParameter);
}
/// <summary>
/// 查询分页数据
/// </summary>
/// <param name="pagination">分页参数</param>
/// <returns>数据列表</returns>
public virtual List<<#=tableName #>> FindList(Pagination pagination)
{
return base.FindList(pagination);
}
/// <summary>
/// 查询表达式查询分页数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <param name="pagination">分页参数</param>
/// <returns>数据列表</returns>
public virtual List<<#=tableName #>> FindList(Expression<Func<<#=tableName #>, bool>> predicate, Pagination pagination)
{
return base.FindList(predicate,pagination);
}
}
}
<#
manager2.EndBlock();
}
manager2.Process(true);
#>
生成后的结果是这样的
文件的内容如下
代码语言:javascript复制//------------------------------------------------------------------------------
// <auto-generated>
// 此代码从T4模板生成。
// 黄正辉(623128629@qq.com)
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;
using System.Data.Common;
using DM.Domain;
using DM.Tools;
using DM.Interface;
using DM.Interface.IRepository;
namespace DM.Repository.BusinessRepository
{
/// <summary>
/// 仓储实现: (Sys_Role)
/// </summary>
public partial class Sys_RoleRepository :RepositoryBase<Sys_Role>, ISys_RoleRepository,IDependency
{
/// <summary>
/// 插入一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Insert(Sys_Role entity)
{
return base.Insert(entity);
}
/// <summary>
/// 插入一个数据列表
/// </summary>
/// <param name="entity">实体列表</param>
/// <returns>受影响行数</returns>
public virtual int Insert(List<Sys_Role> entitys)
{
return base.Insert(entitys);
}
/// <summary>
/// 修改一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Update(Sys_Role entity)
{
return base.Update(entity);
}
/// <summary>
/// 删除一个数据
/// </summary>
/// <param name="entity">实体</param>
/// <returns>受影响行数</returns>
public virtual int Delete(Sys_Role entity)
{
return base.Delete(entity);
}
/// <summary>
/// 根据表达式删除
/// </summary>
/// <param name="predicate">实体</param>
/// <returns>受影响行数</returns>
public virtual int Delete(Expression<Func<Sys_Role, bool>> predicate)
{
return base.Delete(predicate);
}
/// <summary>
/// 根据主键查询一个数据
/// </summary>
/// <param name="keyValue">主键值</param>
/// <returns>实体</returns>
public virtual Sys_Role FindEntity(object keyValue)
{
return base.FindEntity(keyValue);
}
/// <summary>
/// 根据表达式查询一个数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns>实体</returns>
public virtual Sys_Role FindEntity(Expression<Func<Sys_Role, bool>> predicate)
{
return base.FindEntity(predicate);
}
/// <summary>
/// 查询IQueryable列表
/// </summary>
/// <returns>IQueryable列表</returns>
public virtual IQueryable<Sys_Role> IQueryable()
{
return base.IQueryable();
}
/// <summary>
/// 根据表达式查询IQueryable列表数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <returns>IQueryable列表</returns>
public virtual IQueryable<Sys_Role> IQueryable(Expression<Func<Sys_Role, bool>> predicate)
{
return base.IQueryable(predicate);
}
/// <summary>
/// 根据Sql查询数据
/// </summary>
/// <param name="strSql">Sql</param>
/// <returns>数据列表</returns>
public virtual List<Sys_Role> FindList(string strSql)
{
return base.FindList(strSql);
}
/// <summary>
/// 根据Sql查询数据
/// </summary>
/// <param name="strSql">Sql</param>
/// <param name="dbParameter">参数列表</param>
/// <returns>数据列表</returns>
public virtual List<Sys_Role> FindList(string strSql, DbParameter[] dbParameter)
{
return base.FindList(strSql,dbParameter);
}
/// <summary>
/// 查询分页数据
/// </summary>
/// <param name="pagination">分页参数</param>
/// <returns>数据列表</returns>
public virtual List<Sys_Role> FindList(Pagination pagination)
{
return base.FindList(pagination);
}
/// <summary>
/// 查询表达式查询分页数据
/// </summary>
/// <param name="predicate">表达式</param>
/// <param name="pagination">分页参数</param>
/// <returns>数据列表</returns>
public virtual List<Sys_Role> FindList(Expression<Func<Sys_Role, bool>> predicate, Pagination pagination)
{
return base.FindList(predicate,pagination);
}
}
}
这样就完成了批量生成文件的功能了
项目是DM.T4的项目结构
ModelAuto.ttinclude
代码语言:javascript复制<#@ assembly name="System.Core"#>
<#@ assembly name="EnvDTE"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#
class Manager
{
public struct Block {
public String Name;
public int Start, Length;
}
public List<Block> blocks = new List<Block>();
public Block currentBlock;
public Block footerBlock = new Block();
public Block headerBlock = new Block();
public ITextTemplatingEngineHost host;
public ManagementStrategy strategy;
public StringBuilder template;
public String OutputPath { get; set; }
public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
this.host = host;
this.template = template;
OutputPath = String.Empty;
strategy = ManagementStrategy.Create(host);
}
public void StartBlock(String name) {
currentBlock = new Block { Name = name, Start = template.Length };
}
public void StartFooter() {
footerBlock.Start = template.Length;
}
public void EndFooter() {
footerBlock.Length = template.Length - footerBlock.Start;
}
public void StartHeader() {
headerBlock.Start = template.Length;
}
public void EndHeader() {
headerBlock.Length = template.Length - headerBlock.Start;
}
public void EndBlock() {
currentBlock.Length = template.Length - currentBlock.Start;
blocks.Add(currentBlock);
}
public void Process(bool split) {
String header = template.ToString(headerBlock.Start, headerBlock.Length);
String footer = template.ToString(footerBlock.Start, footerBlock.Length);
blocks.Reverse();
foreach(Block block in blocks) {
String fileName = Path.Combine(OutputPath, block.Name);
if (split) {
String content = header template.ToString(block.Start, block.Length) footer;
strategy.CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
} else {
strategy.DeleteFile(fileName);
}
}
}
}
class ManagementStrategy
{
internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
}
internal ManagementStrategy(ITextTemplatingEngineHost host) { }
internal virtual void CreateFile(String fileName, String content) {
File.WriteAllText(fileName, content);
}
internal virtual void DeleteFile(String fileName) {
if (File.Exists(fileName))
File.Delete(fileName);
}
}
class VSManagementStrategy : ManagementStrategy
{
private EnvDTE.ProjectItem templateProjectItem;
internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
IServiceProvider hostServiceProvider = (IServiceProvider)host;
if (hostServiceProvider == null)
throw new ArgumentNullException("Could not obtain hostServiceProvider");
EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
throw new ArgumentNullException("Could not obtain DTE from host");
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
}
internal override void CreateFile(String fileName, String content) {
base.CreateFile(fileName, content);
((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
}
internal override void DeleteFile(String fileName) {
((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
}
private void FindAndDeleteFile(String fileName) {
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
if (projectItem.get_FileNames(0) == fileName) {
projectItem.Delete();
return;
}
}
}
}#>
ModelManager.cs
代码语言:javascript复制using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DM.T4
{
public class ModelManager
{
/// <summary>
/// 数据库连接字符串
/// </summary>
private const string CONNECTION_STRING = "Server=.;Initial Catalog=DocumentManage;User ID=sa;Password=123456";
/// <summary>
/// 用户信息表名
/// </summary>
private const string PERSONINFO_TABLE_NAME = "USERINFO";
/// <summary>
/// 根据表名查询表结构信息
/// </summary>
private const string SELECT_SCHEMA_BY_TABLE_NAME = @"select d.name as 表名 --如果表名相同就返回空
, ddd.value as 表说明 --如果表名相同就返回空
, a.colorder as 字段序号
, a.name as 字段名
, (case
when columnproperty(a.id, a.name, 'IsIdentity') = 1 then
1
else
0
end
) as 是否自增标识
, (case
when
(
select count(*)
from sys.sysobjects --查询主键
where (name in
(
select name
from sys.sysindexes
where (id = a.id)
and (indid in
(
select indid
from sys.sysindexkeys
where (id = a.id)
and (colid in
(
select colid from sys.syscolumns where (id = a.id) and (name = a.name)
)
)
)
)
)
)
and (xtype = 'PK')
) > 0 then
1
else
0
end
) as 主键 --查询主键END
, b.name as 数据类型
, a.length as 占用字节数
, columnproperty(a.id, a.name, 'PRECISION') as 长度
, isnull(columnproperty(a.id, a.name, 'Scale'), 0) as 小数位
, (case
when a.isnullable = 1 then
1
else
0
end
) as 允许空
, isnull(e.text, '') as 缺省值
, isnull(g.value, '') as 备注
from sys.syscolumns a
left join sys.systypes b
on a.xtype = b.xusertype
inner join sys.sysobjects d
on a.id = d.id
and d.xtype = 'U'
and d.name <> 'dtproperties'
left outer join
(
select major_id
, value
from sys.extended_properties
where name = 'MS_Description'
and minor_id = 0
) as ddd
on a.id = ddd.major_id
left join sys.syscomments e
on a.cdefault = e.id
left join sys.extended_properties g
on a.id = g.major_id
and a.colid = g.minor_id
where d.name='{0}'
order by a.id
, a.colorder;";
private const string TABLE_FK_SQL = @"select
a.name as 约束名,
object_name(b.parent_object_id) as 外键表,
c.name as 外键列,
object_name(b.referenced_object_id) as 主健表,
d.name as 主键列
from sys.foreign_keys A
inner join sys.foreign_key_columns B on A.object_id=b.constraint_object_id
inner join sys.columns C on B.parent_object_id=C.object_id and B.parent_column_id=C.column_id
inner join sys.columns D on B.referenced_object_id=d.object_id and B.referenced_column_id=D.column_id
where object_name(b.parent_object_id)!=object_name(b.referenced_object_id)";
/// <summary>
/// 获得数据连接
/// </summary>
/// <returns></returns>
private SqlConnection GetConnection()
{
return new SqlConnection(SqlHelper.sqlConnectionStr);
}
/// <summary>
/// 得到当前用户的所有表名
/// </summary>
/// <returns></returns>
public List<string> GetTableList()
{
string sql = "select table_name from information_schema.tables";
DataTable dt = SqlHelper.ExecuteDataTable(sql);
List<string> list = new List<string>();
if (dt != null && dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i )
{
list.Add(dt.Rows[i][0].ToString());
}
}
return list;
}
/// <summary>
/// 得到所有表主外键关系
/// </summary>
/// <returns></returns>
public List<FK> GetFK()
{
DataTable dt = SqlHelper.ExecuteDataTable(TABLE_FK_SQL);
List<FK> lst = new List<FK>();
for (int i = 0; i < dt.Rows.Count; i )
{
FK fk = new FK()
{
FKName = dt.Rows[i]["约束名"].ToString(),
WJ_Table = dt.Rows[i]["外键表"].ToString(),
WJ_Field = dt.Rows[i]["外键列"].ToString(),
ZJ_Table = dt.Rows[i]["主健表"].ToString(),
ZJ_Field = dt.Rows[i]["主键列"].ToString()
};
lst.Add(fk);
}
return lst;
}
/// <summary>
/// 释放连接
/// </summary>
/// <param name="con"></param>
private void ReleaseConnection(SqlConnection con)
{
if (con != null)
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
public DataTable GetTableSchema(string tableName)
{
DataTable dt = SqlHelper.ExecuteDataTable(string.Format(SELECT_SCHEMA_BY_TABLE_NAME, tableName));
return dt;
}
/// <summary>
/// SQL[不完善,需要的自己改造]
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public string TransFromSqlType(string type)
{
type = type.ToLower();
switch (type)
{
case "int": return "int";
case "bigint": return "Int64";
case "smallint": return "Int16";
case "text":
case "char":
case "nchar":
case "ntext":
case "nvarchar":
case "varchar": return "string";
case "varbinary":
case "image":
case "binary": return "Byte[]";
case "tinyint": return "byte";
case "bit": return "bool";
case "date":
case "time":
case "smalldatetime":
case "timestamp":
case "datetime": return "DateTime";
case "money":
case "numeric":
case "smallmoney":
case "decimal": return "decimal";
case "float": return "double";
case "real": return "Single";
default: return "string";
}
}
}
public class FK
{
public string FKName { get; set; }
public string WJ_Table { get; set; }
public string WJ_Field { get; set; }
public string ZJ_Table { get; set; }
public string ZJ_Field { get; set; }
}
}
SqlHelper.cs
代码语言:javascript复制using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DM.T4
{
public class SqlHelper
{
public static string sqlConnectionStr = "Server=.;Initial Catalog=DocumentManage;User ID=sa;Password=123456";
public static DataTable ExecuteDataTable(string sql, params SqlParameter[] paramList)
{
using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
{
conn.Open();
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = sql;
command.Parameters.AddRange(paramList);
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(dt);
return dt;
}
}
}
public static int ExecuteNonQuery(string sql, params SqlParameter[] paramList)
{
using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
{
conn.Open();
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = sql;
command.Parameters.AddRange(paramList);
return command.ExecuteNonQuery();
}
}
}
public static object ExecuteScalar(string sql, params SqlParameter[] paramList)
{
using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
{
conn.Open();
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = sql;
command.Parameters.AddRange(paramList);
return command.ExecuteScalar();
}
}
}
}
}