在entity项目里新建模板DBEntity.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ include file="$(SolutionDir)\Packages\T4.TemplateFileManager.2.1.2\tools\ttinc\TemplateFilemanager.CS.ttinclude" #>
<#@ include file="$(SolutionDir)\Packages\T4.TemplateFileManager.2.1.2\tools\ttinc\DbHelper.CS.ttinclude" #>
<#@ output extension=".txt" #> <#
// Recommended editor: Tangible T4 Editor (http://t4-editor.tangible-engineering.com/Download_T4Editor_Plus_ModelingTools.html)
// after save SimpleSample.tt, the output will be generated in the TestFolder of the project
var fileProperties = new FileProperties()
{
BuildAction = BuildAction.Compile
}; var fileManager = TemplateFileManager.Create(this);
fileManager.IsAutoIndentEnabled = true;
fileManager.CanOverwriteExistingFile = true; fileManager.StartHeader();
#>
//<summary file="$filename$" company="ldy">
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码是根据模板生成的。
//
// 手动更改此文件可能会导致应用程序中发生异常行为。
// 如果重新生成代码,则将覆盖对此文件的手动更改。//出自 http://www.cnblogs.com/ahjesus 尊重作者辛苦劳动成果,转载请注明出处,谢谢!
// </auto-generated>
//------------------------------------------------------------------------------
// </summary>
<#
fileManager.EndBlock(); var paramTmpl = ParamTextTemplate.Create(this.Host);
var session = ParamTextTemplate.GetSessionObject();
var DbTables = DbHelper.GetDbTables(config.ConnectionString, config.DbDatabase);
foreach(var table in DbTables){
fileManager.StartNewFile(table.TableName + ".cs", config.NameSpace,"",fileProperties);
session["ConnectionString"] = config.ConnectionString;
session["DbDatabase"] = config.DbDatabase;
session["NameSpace"] = config.NameSpace;
session["TableName"] = table.TableName;
string output = paramTmpl.TransformText("EntityContent.tt", session);
this.Write(output);
} fileManager.Process();
#> <#+
public class config
{
public static readonly string ConnectionString="Data Source=192.168.1.10;Initial Catalog=TongJi;User ID=sa;Password=123456";
public static readonly string DbDatabase="TongJi";
public static readonly string TableName="TAd";
public static readonly string NameSpace="__System.Entity";
}
#>

再新建EntityContent.tt

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ parameter name="ConnectionString" type="System.String" #>
<#@ parameter name="DbDatabase" type="System.String" #>
<#@ parameter name="TableName" type="System.String" #>
<#@ parameter name="NameSpace" type="System.String" #>
<#@ include file="$(SolutionDir)\Packages\T4.TemplateFileManager.2.1.2\tools\ttinc\DbHelper.CS.ttinclude" #>
<#@ output extension=".txt" #>
<#if(ConnectionString!=null&&DbDatabase!=null&&TableName!=null&&NameSpace!=null){#>
using System;
using System.Collections.Generic;
namespace <#=NameSpace#>
{
public class <#=TableName#> : BaseEntity
{
<#foreach(DbColumn column in DbHelper.GetDbColumns(ConnectionString, DbDatabase, TableName)){#>
/// <summary>
/// <#=GetRemark(column.Remark)#>
/// </summary>
public <#=column.CSharpType#><#if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
<#}#>
}
}
<#}#> <#+
public string GetRemark(string str){
char[] strArr =str.ToCharArray();
string newStr = "";
foreach (char cr in strArr)
{
if (cr == (char))
{
newStr = newStr+cr.ToString()+"///";
}
else{
newStr += cr.ToString();
}
}
return newStr;
}
#>

注意到有一段

<#@ include file="$(SolutionDir)\Packages\T4.TemplateFileManager.2.1.2\tools\ttinc\TemplateFilemanager.CS.ttinclude" #>
<#@ include file="$(SolutionDir)\Packages\T4.TemplateFileManager.2.1.2\tools\ttinc\DbHelper.CS.ttinclude"  #>
在解决方案文件夹目录下的Packages(没有就新建)里新建T4.TemplateFileManager.2.1.2\tools\ttinc\这个目录

新建文件TemplateFilemanager.CS.ttinclude

<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#+
public class DbHelper
{
#region GetDbTables public static List<DbTable> GetDbTables(string connectionString, string database, string tables = null)
{ if (!string.IsNullOrEmpty(tables))
{
tables = string.Format(" and obj.name in ('{0}')", tables.Replace(",", "','"));
}
#region SQL
string sql = string.Format(@"SELECT
obj.name tablename,
schem.name schemname,
idx.rows,
CAST
(
CASE
WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1
ELSE 0
END
AS BIT) HasPrimaryKey
from {0}.sys.objects obj
inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1
INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_id
where type='U' {1}
order by obj.name", database, tables);
#endregion
DataTable dt = GetDataTable(connectionString, sql);
return dt.Rows.Cast<DataRow>().Select(row => new DbTable
{
TableName = row.Field<string>("tablename"),
SchemaName = row.Field<string>("schemname"),
Rows = row.Field<int>("rows"),
HasPrimaryKey = row.Field<bool>("HasPrimaryKey")
}).ToList();
}
#endregion #region GetDbColumns public static List<DbColumn> GetDbColumns(string connectionString, string database, string tableName, string schema = "dbo")
{
#region SQL
string sql = string.Format(@"
WITH indexCTE AS
(
SELECT
ic.column_id,
ic.index_column_id,
ic.object_id
FROM {0}.sys.indexes idx
INNER JOIN {0}.sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_id
WHERE idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1
)
select
colm.column_id ColumnID,
CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,
colm.name ColumnName,
systype.name ColumnType,
colm.is_identity IsIdentity,
colm.is_nullable IsNullable,
cast(colm.max_length as int) ByteLength,
(
case
when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2
when systype.name='nchar' and colm.max_length>0 then colm.max_length/2
when systype.name='ntext' and colm.max_length>0 then colm.max_length/2
else colm.max_length
end
) CharLength,
cast(colm.precision as int) Precision,
cast(colm.scale as int) Scale,
prop.value Remark
from {0}.sys.columns colm
inner join {0}.sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_id
left join {0}.sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_id
LEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id
where colm.object_id=OBJECT_ID(@tableName)
order by colm.column_id", database);
#endregion
SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, ) { Value = string.Format("{0}.{1}.{2}", database, schema, tableName) };
DataTable dt = GetDataTable(connectionString, sql, param);
return dt.Rows.Cast<DataRow>().Select(row => new DbColumn()
{
ColumnID = row.Field<int>("ColumnID"),
IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),
ColumnName = row.Field<string>("ColumnName"),
ColumnType = row.Field<string>("ColumnType"),
IsIdentity = row.Field<bool>("IsIdentity"),
IsNullable = row.Field<bool>("IsNullable"),
ByteLength = row.Field<int>("ByteLength"),
CharLength = row.Field<int>("CharLength"),
Scale = row.Field<int>("Scale"),
Remark = row["Remark"].ToString()
}).ToList();
} #endregion #region GetDataTable public static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = commandText;
command.Parameters.AddRange(parms);
SqlDataAdapter adapter = new SqlDataAdapter(command); DataTable dt = new DataTable();
adapter.Fill(dt); return dt;
}
} #endregion
} #region DbTable
/// <summary>
/// 表结构
/// </summary>
public sealed class DbTable
{
/// <summary>
/// 表名称
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 表的架构
/// </summary>
public string SchemaName { get; set; }
/// <summary>
/// 表的记录数
/// </summary>
public int Rows { get; set; } /// <summary>
/// 是否含有主键
/// </summary>
public bool HasPrimaryKey { get; set; }
}
#endregion #region DbColumn
/// <summary>
/// 表字段结构
/// </summary>
public sealed class DbColumn
{
/// <summary>
/// 字段ID
/// </summary>
public int ColumnID { get; set; } /// <summary>
/// 是否主键
/// </summary>
public bool IsPrimaryKey { get; set; } /// <summary>
/// 字段名称
/// </summary>
public string ColumnName { get; set; } /// <summary>
/// 字段类型
/// </summary>
public string ColumnType { get; set; } /// <summary>
/// 数据库类型对应的C#类型
/// </summary>
public string CSharpType
{
get
{
return SqlServerDbTypeMap.MapCsharpType(ColumnType);
}
} /// <summary>
///
/// </summary>
public Type CommonType
{
get
{
return SqlServerDbTypeMap.MapCommonType(ColumnType);
}
} /// <summary>
/// 字节长度
/// </summary>
public int ByteLength { get; set; } /// <summary>
/// 字符长度
/// </summary>
public int CharLength { get; set; } /// <summary>
/// 小数位
/// </summary>
public int Scale { get; set; } /// <summary>
/// 是否自增列
/// </summary>
public bool IsIdentity { get; set; } /// <summary>
/// 是否允许空
/// </summary>
public bool IsNullable { get; set; } /// <summary>
/// 描述
/// </summary>
public string Remark { get; set; }
}
#endregion #region SqlServerDbTypeMap public class SqlServerDbTypeMap
{
public static string MapCsharpType(string dbtype)
{
if (string.IsNullOrEmpty(dbtype)) return dbtype;
dbtype = dbtype.ToLower();
string csharpType = "object";
switch (dbtype)
{
case "bigint": csharpType = "long"; break;
case "binary": csharpType = "byte[]"; break;
case "bit": csharpType = "bool"; break;
case "char": csharpType = "string"; break;
case "date": csharpType = "DateTime"; break;
case "datetime": csharpType = "DateTime"; break;
case "datetime2": csharpType = "DateTime"; break;
case "datetimeoffset": csharpType = "DateTimeOffset"; break;
case "decimal": csharpType = "decimal"; break;
case "float": csharpType = "double"; break;
case "image": csharpType = "byte[]"; break;
case "int": csharpType = "int"; break;
case "money": csharpType = "decimal"; break;
case "nchar": csharpType = "string"; break;
case "ntext": csharpType = "string"; break;
case "numeric": csharpType = "decimal"; break;
case "nvarchar": csharpType = "string"; break;
case "real": csharpType = "Single"; break;
case "smalldatetime": csharpType = "DateTime"; break;
case "smallint": csharpType = "short"; break;
case "smallmoney": csharpType = "decimal"; break;
case "sql_variant": csharpType = "object"; break;
case "sysname": csharpType = "object"; break;
case "text": csharpType = "string"; break;
case "time": csharpType = "TimeSpan"; break;
case "timestamp": csharpType = "byte[]"; break;
case "tinyint": csharpType = "byte"; break;
case "uniqueidentifier": csharpType = "Guid"; break;
case "varbinary": csharpType = "byte[]"; break;
case "varchar": csharpType = "string"; break;
case "xml": csharpType = "string"; break;
default: csharpType = "object"; break;
}
return csharpType;
} public static Type MapCommonType(string dbtype)
{
if (string.IsNullOrEmpty(dbtype)) return Type.Missing.GetType();
dbtype = dbtype.ToLower();
Type commonType = typeof(object);
switch (dbtype)
{
case "bigint": commonType = typeof(long); break;
case "binary": commonType = typeof(byte[]); break;
case "bit": commonType = typeof(bool); break;
case "char": commonType = typeof(string); break;
case "date": commonType = typeof(DateTime); break;
case "datetime": commonType = typeof(DateTime); break;
case "datetime2": commonType = typeof(DateTime); break;
case "datetimeoffset": commonType = typeof(DateTimeOffset); break;
case "decimal": commonType = typeof(decimal); break;
case "float": commonType = typeof(double); break;
case "image": commonType = typeof(byte[]); break;
case "int": commonType = typeof(int); break;
case "money": commonType = typeof(decimal); break;
case "nchar": commonType = typeof(string); break;
case "ntext": commonType = typeof(string); break;
case "numeric": commonType = typeof(decimal); break;
case "nvarchar": commonType = typeof(string); break;
case "real": commonType = typeof(Single); break;
case "smalldatetime": commonType = typeof(DateTime); break;
case "smallint": commonType = typeof(short); break;
case "smallmoney": commonType = typeof(decimal); break;
case "sql_variant": commonType = typeof(object); break;
case "sysname": commonType = typeof(object); break;
case "text": commonType = typeof(string); break;
case "time": commonType = typeof(TimeSpan); break;
case "timestamp": commonType = typeof(byte[]); break;
case "tinyint": commonType = typeof(byte); break;
case "uniqueidentifier": commonType = typeof(Guid); break;
case "varbinary": commonType = typeof(byte[]); break;
case "varchar": commonType = typeof(string); break;
case "xml": commonType = typeof(string); break;
default: commonType = typeof(object); break;
}
return commonType;
}
}
#endregion #>

新建TemplateFilemanager.CS.ttinclude

<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq"#>
<#@ assembly name="System.Windows.Forms" #>
<#@ assembly name="EnvDTE"#>
<#@ assembly name="EnvDTE80" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.10.0"#>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop "#>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop"#>
<#@ import namespace="System" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.Objects" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data.Objects.DataClasses" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="Microsoft.CSharp"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#+
/*
This software is supplied "AS IS". The authors disclaim all warranties,
expressed or implied, including, without limitation, the warranties of
merchantability and of fitness for any purpose. The authors assume no
liability for direct, indirect, incidental, special, exemplary, or
consequential damages, which may result from the use of this software,
even if advised of the possibility of such damage. The TemplateFileManager is based on EntityFrameworkTemplateFileManager (EFTFM) from MS. Differences to EFTFM
Version 2.1.2
- Bugfix Exception when solution contains wix-projects, reported by jturner
Version 2.1:
- Replace Enum BuildAction with class for more flexibility
Version 2:
- StartHeader works with Parameter $filename$
- StartNewFile has a new named parameter FileProperties
- Support for:
- BuildAction
- CustomTool
- user defined parameter for using in StartHeader-Block
- Property IsAutoIndentEnabled for support Format Document (C#, VB) when set to true Version: 1.1
Add method WriteLineToBuildPane, WriteToBuildPane Version 1:
- StartNewFile with named parameters projectName and folderName for generating files to different locations.
- Property CanOverrideExistingFile, to define whether existing files are can overwritten
- Property Encoding Encode type for output files.
*/ /// <summary>
/// Writes a line to the build pane in visual studio and activates it
/// </summary>
/// <param name="message">Text to output - a \n is appended</param>
void WriteLineToBuildPane (string message){
WriteLineToBuildPane(String.Format("{0}\n", message));
} /// <summary>
/// Writes a string to the build pane in visual studio and activates it
/// </summary>
/// <param name="message">Text to output</param>
void WriteToBuildPane (string message){
IVsOutputWindow outWindow = (this.Host as IServiceProvider).GetService(
typeof( SVsOutputWindow ) ) as IVsOutputWindow;
Guid generalPaneGuid =
Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid;
// P.S. There's also the GUID_OutWindowDebugPane available.
IVsOutputWindowPane generalPane;
outWindow.GetPane( ref generalPaneGuid , out generalPane );
generalPane.OutputString( message );
generalPane.Activate(); // Brings this pane into view
} /// <summary>
/// Responsible for marking the various sections of the generation,
/// so they can be split up into separate files and projects
/// </summary>
/// <author>R. Leupold</author>
public class TemplateFileManager
{
private EnvDTE.ProjectItem templateProjectItem;
private Action<string> checkOutAction;
private Action<IEnumerable<OutputFile>> projectSyncAction;
private EnvDTE.DTE dte;
private List<string> templatePlaceholderList = new List<string>(); /// <summary>
/// Creates files with VS sync
/// </summary>
public static TemplateFileManager Create(object textTransformation)
{
DynamicTextTransformation2 transformation = DynamicTextTransformation2.Create(textTransformation);
IDynamicHost2 host = transformation.Host;
return new TemplateFileManager(transformation);
} private readonly List<Block> files = new List<Block>();
private readonly Block footer = new Block();
private readonly Block header = new Block();
private readonly DynamicTextTransformation2 _textTransformation; // reference to the GenerationEnvironment StringBuilder on the
// TextTransformation object
private readonly StringBuilder _generationEnvironment; private Block currentBlock; /// <summary>
/// Initializes an TemplateFileManager Instance with the
/// TextTransformation (T4 generated class) that is currently running
/// </summary>
private TemplateFileManager(object textTransformation)
{
if (textTransformation == null)
{
throw new ArgumentNullException("textTransformation");
} _textTransformation = DynamicTextTransformation2.Create(textTransformation);
_generationEnvironment = _textTransformation.GenerationEnvironment; var hostServiceProvider = _textTransformation.Host.AsIServiceProvider();
if (hostServiceProvider == null)
{
throw new ArgumentNullException("Could not obtain hostServiceProvider");
} dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
{
throw new ArgumentNullException("Could not obtain DTE from host");
} this.templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile);
this.CanOverrideExistingFile = true;
this.IsAutoIndentEnabled = false;
this.Encoding = System.Text.Encoding.UTF8;
checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames);
} /// <summary>
/// If set to false, existing files are not overwritten
/// </summary>
/// <returns></returns>
public bool CanOverrideExistingFile { get; set; }
public bool CanOverwriteExistingFile { get { return this.CanOverrideExistingFile; } set { this.CanOverrideExistingFile = value;} } /// <summary>
/// If set to true, output files (c#, vb) are formatted based on the vs settings.
/// </summary>
/// <returns></returns>
public bool IsAutoIndentEnabled { get; set; } /// <summary>
/// Defines Encoding format for generated output file. (Default UTF8)
/// </summary>
/// <returns></returns>
public System.Text.Encoding Encoding { get; set; } /// <summary>
/// Marks the end of the last file if there was one, and starts a new
/// and marks this point in generation as a new file.
/// </summary>
/// <param name="name">Filename</param>
/// <param name="projectName">Name of the target project for the new file.</param>
/// <param name="folderName">Name of the target folder for the new file.</param>
/// <param name="fileProperties">File property settings in vs for the new File</param>
public void StartNewFile(string name
, string projectName = "", string folderName = "", FileProperties fileProperties = null)
{
if (String.IsNullOrWhiteSpace(name) == true)
{
throw new ArgumentException("name");
} CurrentBlock = new Block
{
Name = name,
ProjectName = projectName,
FolderName = folderName,
FileProperties = fileProperties ?? new FileProperties()
};
} public void StartFooter()
{
CurrentBlock = footer;
} public void StartHeader()
{
CurrentBlock = header;
} public void EndBlock()
{
if (CurrentBlock == null)
{
return;
} CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; if (CurrentBlock != header && CurrentBlock != footer)
{
files.Add(CurrentBlock);
} currentBlock = null;
} /// <summary>
/// Produce the template output files.
/// </summary>
public virtual IEnumerable<OutputFile> Process(bool split = true)
{
var list = new List<OutputFile>(); if (split)
{
EndBlock(); var headerText = _generationEnvironment.ToString(header.Start, header.Length);
var footerText = _generationEnvironment.ToString(footer.Start, footer.Length);
files.Reverse(); foreach (var block in files)
{
var outputPath = VSHelper.GetOutputPath(dte, block, Path.GetDirectoryName(_textTransformation.Host.TemplateFile));
var fileName = Path.Combine(outputPath, block.Name);
var content = this.ReplaceParameter(headerText, block) +
_generationEnvironment.ToString(block.Start, block.Length) +
footerText; var file = new OutputFile
{
FileName = fileName,
ProjectName = block.ProjectName,
FolderName = block.FolderName,
FileProperties = block.FileProperties,
Content = content
}; CreateFile(file);
_generationEnvironment.Remove(block.Start, block.Length); list.Add(file);
}
} projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(list, null, null));
this.CleanUpTemplatePlaceholders();
var items = VSHelper.GetOutputFilesAsProjectItems(this.dte, list);
this.WriteVsProperties(items, list); if (this.IsAutoIndentEnabled == true && split == true)
{
this.FormatProjectItems(items);
} this.WriteLog(list); return list;
} private void FormatProjectItems(IEnumerable<EnvDTE.ProjectItem> items)
{
foreach (var item in items)
{
this._textTransformation.WriteLine(
VSHelper.ExecuteVsCommand(this.dte, item, "Edit.FormatDocument")); //, "Edit.RemoveAndSort"));
this._textTransformation.WriteLine("//-> " + item.Name);
}
} private void WriteVsProperties(IEnumerable<EnvDTE.ProjectItem> items, IEnumerable<OutputFile> outputFiles)
{
foreach (var file in outputFiles)
{
var item = items.Where(p => p.Name == Path.GetFileName(file.FileName)).FirstOrDefault();
if (item == null) continue; if (String.IsNullOrEmpty(file.FileProperties.CustomTool) == false)
{
VSHelper.SetPropertyValue(item, "CustomTool", file.FileProperties.CustomTool);
} if (String.IsNullOrEmpty(file.FileProperties.BuildActionString) == false)
{
VSHelper.SetPropertyValue(item, "ItemType", file.FileProperties.BuildActionString);
}
}
} private string ReplaceParameter(string text, Block block)
{
if (String.IsNullOrEmpty(text) == false)
{
text = text.Replace("$filename$", block.Name);
} foreach (var item in block.FileProperties.TemplateParameter.AsEnumerable())
{
text = text.Replace(item.Key, item.Value);
} return text;
} /// <summary>
/// Write log to the default output file.
/// </summary>
/// <param name="list"></param>
private void WriteLog(IEnumerable<OutputFile> list)
{
this._textTransformation.WriteLine("// Generated helper templates");
foreach (var item in templatePlaceholderList)
{
this._textTransformation.WriteLine("// " + this.GetDirectorySolutionRelative(item));
} this._textTransformation.WriteLine("// Generated items");
foreach (var item in list)
{
this._textTransformation.WriteLine("// " + this.GetDirectorySolutionRelative(item.FileName));
}
} /// <summary>
/// Removes old template placeholders from the solution.
/// </summary>
private void CleanUpTemplatePlaceholders()
{
string[] activeTemplateFullNames = this.templatePlaceholderList.ToArray();
string[] allHelperTemplateFullNames = VSHelper.GetAllSolutionItems(this.dte)
.Where(p => p.Name == VSHelper.GetTemplatePlaceholderName(this.templateProjectItem))
.Select(p => VSHelper.GetProjectItemFullPath(p))
.ToArray(); var delta = allHelperTemplateFullNames.Except(activeTemplateFullNames).ToArray(); var dirtyHelperTemplates = VSHelper.GetAllSolutionItems(this.dte)
.Where(p => delta.Contains(VSHelper.GetProjectItemFullPath(p))); foreach (ProjectItem item in dirtyHelperTemplates)
{
if (item.ProjectItems != null)
{
foreach (ProjectItem subItem in item.ProjectItems)
{
subItem.Remove();
}
} item.Remove();
}
} /// <summary>
/// Gets a list of helper templates from the log.
/// </summary>
/// <returns>List of generated helper templates.</returns>
private string[] GetPreviousTemplatePlaceholdersFromLog()
{
string path = Path.GetDirectoryName(this._textTransformation.Host.ResolvePath(this._textTransformation.Host.TemplateFile));
string file1 = Path.GetFileNameWithoutExtension(this._textTransformation.Host.TemplateFile) + ".txt";
string contentPrevious = File.ReadAllText(Path.Combine(path, file1)); var result = contentPrevious
.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split(new[] { "=>" }, StringSplitOptions.RemoveEmptyEntries).First())
.Select(x => Regex.Replace(x, "//", String.Empty).Trim())
.Where(x => x.EndsWith(VSHelper.GetTemplatePlaceholderName(this.templateProjectItem)))
.ToArray(); return result;
} private string GetDirectorySolutionRelative(string fullName)
{
int slnPos = fullName.IndexOf(Path.GetFileNameWithoutExtension(this.dte.Solution.FileName));
if (slnPos < )
{
slnPos = ;
} return fullName.Substring(slnPos);
} protected virtual void CreateFile(OutputFile file)
{
if (this.CanOverrideExistingFile == false && File.Exists(file.FileName) == true)
{
return;
} if (IsFileContentDifferent(file))
{
CheckoutFileIfRequired(file.FileName);
File.WriteAllText(file.FileName, file.Content, this.Encoding);
}
} protected bool IsFileContentDifferent(OutputFile file)
{
return !(File.Exists(file.FileName) && File.ReadAllText(file.FileName) == file.Content);
} private Block CurrentBlock
{
get { return currentBlock; }
set
{
if (CurrentBlock != null)
{
EndBlock();
} if (value != null)
{
value.Start = _generationEnvironment.Length;
} currentBlock = value;
}
} private void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<OutputFile> keepFileNames)
{
var groupedFileNames = from f in keepFileNames
group f by new { f.ProjectName, f.FolderName }
into l
select new {
ProjectName = l.Key.ProjectName,
FolderName = l.Key.FolderName,
FirstItem = l.First(),
OutputFiles = l
}; this.templatePlaceholderList.Clear(); foreach (var item in groupedFileNames)
{
EnvDTE.ProjectItem pi = VSHelper.GetTemplateProjectItem(templateProjectItem.DTE, item.FirstItem, templateProjectItem);
ProjectSyncPart(pi, item.OutputFiles); if (pi.Name.EndsWith("txt4"))
this.templatePlaceholderList.Add(VSHelper.GetProjectItemFullPath(pi));
} // clean up
bool hasDefaultItems = groupedFileNames.Where(f => String.IsNullOrEmpty(f.ProjectName) && String.IsNullOrEmpty(f.FolderName)).Count() > ;
if (hasDefaultItems == false)
{
ProjectSyncPart(templateProjectItem, new List<OutputFile>());
}
} private static void ProjectSyncPart(EnvDTE.ProjectItem templateProjectItem, IEnumerable<OutputFile> keepFileNames)
{
var keepFileNameSet = new HashSet<OutputFile>(keepFileNames);
var projectFiles = new Dictionary<string, EnvDTE.ProjectItem>();
var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[]); foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
{
projectFiles.Add(projectItem.FileNames[], projectItem);
} // Remove unused items from the project
foreach (var pair in projectFiles)
{
bool isNotFound = keepFileNames.Where(f=>f.FileName == pair.Key).Count() == ;
if (isNotFound == true
&& !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + "."))
{
pair.Value.Delete();
}
} // Add missing files to the project
foreach (var fileName in keepFileNameSet)
{
if (!projectFiles.ContainsKey(fileName.FileName))
{
templateProjectItem.ProjectItems.AddFromFile(fileName.FileName);
}
}
} private void CheckoutFileIfRequired(string fileName)
{
if (dte.SourceControl == null
|| !dte.SourceControl.IsItemUnderSCC(fileName)
|| dte.SourceControl.IsItemCheckedOut(fileName))
{
return;
} // run on worker thread to prevent T4 calling back into VS
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}
} /// <summary>
/// Responsible creating an instance that can be passed
/// to helper classes that need to access the TextTransformation
/// members. It accesses member by name and signature rather than
/// by type. This is necessary when the
/// template is being used in Preprocessed mode
/// and there is no common known type that can be
/// passed instead
/// </summary>
public class DynamicTextTransformation2
{
private object _instance;
IDynamicHost2 _dynamicHost; private readonly MethodInfo _write;
private readonly MethodInfo _writeLine;
private readonly PropertyInfo _generationEnvironment;
private readonly PropertyInfo _errors;
private readonly PropertyInfo _host; /// <summary>
/// Creates an instance of the DynamicTextTransformation class around the passed in
/// TextTransformation shapped instance passed in, or if the passed in instance
/// already is a DynamicTextTransformation, it casts it and sends it back.
/// </summary>
public static DynamicTextTransformation2 Create(object instance)
{
if (instance == null)
{
throw new ArgumentNullException("instance");
} DynamicTextTransformation2 textTransformation = instance as DynamicTextTransformation2;
if (textTransformation != null)
{
return textTransformation;
} return new DynamicTextTransformation2(instance);
} private DynamicTextTransformation2(object instance)
{
_instance = instance;
Type type = _instance.GetType();
_write = type.GetMethod("Write", new Type[] { typeof(string) });
_writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) });
_generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic);
_host = type.GetProperty("Host");
_errors = type.GetProperty("Errors");
} /// <summary>
/// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property
/// </summary>
public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } /// <summary>
/// Gets the value of the wrapped TextTranformation instance's Errors property
/// </summary>
public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } /// <summary>
/// Calls the wrapped TextTranformation instance's Write method.
/// </summary>
public void Write(string text)
{
_write.Invoke(_instance, new object[] { text });
} /// <summary>
/// Calls the wrapped TextTranformation instance's WriteLine method.
/// </summary>
public void WriteLine(string text)
{
_writeLine.Invoke(_instance, new object[] { text });
} /// <summary>
/// Gets the value of the wrapped TextTranformation instance's Host property
/// if available (shows up when hostspecific is set to true in the template directive) and returns
/// the appropriate implementation of IDynamicHost
/// </summary>
public IDynamicHost2 Host
{
get
{
if (_dynamicHost == null)
{
if(_host == null)
{
_dynamicHost = new NullHost2();
}
else
{
_dynamicHost = new DynamicHost2(_host.GetValue(_instance, null));
}
}
return _dynamicHost;
}
}
} /// <summary>
/// Reponsible for abstracting the use of Host between times
/// when it is available and not
/// </summary>
public interface IDynamicHost2
{
/// <summary>
/// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue
/// </summary>
string ResolveParameterValue(string id, string name, string otherName); /// <summary>
/// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath
/// </summary>
string ResolvePath(string path); /// <summary>
/// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile
/// </summary>
string TemplateFile { get; } /// <summary>
/// Returns the Host instance cast as an IServiceProvider
/// </summary>
IServiceProvider AsIServiceProvider();
} /// <summary>
/// Reponsible for implementing the IDynamicHost as a dynamic
/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface
/// rather than type dependent wrapper. We don't use the
/// interface type so that the code can be run in preprocessed mode
/// on a .net framework only installed machine.
/// </summary>
public class DynamicHost2 : IDynamicHost2
{
private readonly object _instance;
private readonly MethodInfo _resolveParameterValue;
private readonly MethodInfo _resolvePath;
private readonly PropertyInfo _templateFile; /// <summary>
/// Creates an instance of the DynamicHost class around the passed in
/// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in.
/// </summary>
public DynamicHost2(object instance)
{
_instance = instance;
Type type = _instance.GetType();
_resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) });
_resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) });
_templateFile = type.GetProperty("TemplateFile"); } /// <summary>
/// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue
/// </summary>
public string ResolveParameterValue(string id, string name, string otherName)
{
return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName });
} /// <summary>
/// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath
/// </summary>
public string ResolvePath(string path)
{
return (string)_resolvePath.Invoke(_instance, new object[] { path });
} /// <summary>
/// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile
/// </summary>
public string TemplateFile
{
get
{
return (string)_templateFile.GetValue(_instance, null);
}
} /// <summary>
/// Returns the Host instance cast as an IServiceProvider
/// </summary>
public IServiceProvider AsIServiceProvider()
{
return _instance as IServiceProvider;
}
} /// <summary>
/// Reponsible for implementing the IDynamicHost when the
/// Host property is not available on the TextTemplating type. The Host
/// property only exists when the hostspecific attribute of the template
/// directive is set to true.
/// </summary>
public class NullHost2 : IDynamicHost2
{
/// <summary>
/// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue
/// that simply retuns null.
/// </summary>
public string ResolveParameterValue(string id, string name, string otherName)
{
return null;
} /// <summary>
/// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath
/// that simply retuns the path passed in.
/// </summary>
public string ResolvePath(string path)
{
return path;
} /// <summary>
/// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile
/// that returns null.
/// </summary>
public string TemplateFile
{
get
{
return null;
}
} /// <summary>
/// Returns null.
/// </summary>
public IServiceProvider AsIServiceProvider()
{
return null;
}
} public sealed class Block
{
public String Name;
public int Start, Length;
public string ProjectName { get; set; }
public string FolderName { get; set; }
public FileProperties FileProperties { get; set; }
} public class ParamTextTemplate
{
private ITextTemplatingEngineHost Host { get; set; } private ParamTextTemplate(ITextTemplatingEngineHost host)
{
this.Host = host;
} public static ParamTextTemplate Create(ITextTemplatingEngineHost host)
{
return new ParamTextTemplate(host);
} public static TextTemplatingSession GetSessionObject()
{
return new TextTemplatingSession();
} public string TransformText(string templateName, TextTemplatingSession session)
{
return this.GetTemplateContent(templateName, session);
} public string GetTemplateContent(string templateName, TextTemplatingSession session)
{
string fullName = this.Host.ResolvePath(templateName);
string templateContent = File.ReadAllText(fullName); var sessionHost = this.Host as ITextTemplatingSessionHost;
sessionHost.Session = session; Engine engine = new Engine();
return engine.ProcessTemplate(templateContent, this.Host);
}
} public class VSHelper
{
/// <summary>
/// Execute Visual Studio commands against the project item.
/// </summary>
/// <param name="item">The current project item.</param>
/// <param name="command">The vs command as string.</param>
/// <returns>An error message if the command fails.</returns>
public static string ExecuteVsCommand(EnvDTE.DTE dte, EnvDTE.ProjectItem item, params string[] command)
{
if (item == null)
{
throw new ArgumentNullException("item");
} string error = String.Empty; try
{
EnvDTE.Window window = item.Open();
window.Activate(); foreach (var cmd in command)
{
if (String.IsNullOrWhiteSpace(cmd) == true)
{
continue;
} EnvDTE80.DTE2 dte2 = dte as EnvDTE80.DTE2;
dte2.ExecuteCommand(cmd, String.Empty);
} item.Save();
window.Visible = false;
// window.Close(); // Ends VS, but not the tab :(
}
catch (Exception ex)
{
error = String.Format("Error processing file {0} {1}", item.Name, ex.Message);
} return error;
} /// <summary>
/// Sets a property value for the vs project item.
/// </summary>
public static void SetPropertyValue(EnvDTE.ProjectItem item, string propertyName, object value)
{
EnvDTE.Property property = item.Properties.Item(propertyName);
if (property == null)
{
throw new ArgumentException(String.Format("The property {0} was not found.", propertyName));
}
else
{
property.Value = value;
}
} public static IEnumerable<ProjectItem> GetOutputFilesAsProjectItems(EnvDTE.DTE dte, IEnumerable<OutputFile> outputFiles)
{
var fileNames = (from o in outputFiles
select Path.GetFileName(o.FileName)).ToArray(); return VSHelper.GetAllSolutionItems(dte).Where(f => fileNames.Contains(f.Name));
} public static string GetOutputPath(EnvDTE.DTE dte, Block block, string defaultPath)
{
if (String.IsNullOrEmpty(block.ProjectName) == true && String.IsNullOrEmpty(block.FolderName) == true)
{
return defaultPath;
} EnvDTE.Project prj = null;
EnvDTE.ProjectItem item = null; if (String.IsNullOrEmpty(block.ProjectName) == false)
{
prj = GetProject(dte, block.ProjectName);
} if (String.IsNullOrEmpty(block.FolderName) == true && prj != null)
{
return Path.GetDirectoryName(prj.FullName);
}
else if (prj != null && String.IsNullOrEmpty(block.FolderName) == false)
{
item = GetAllProjectItemsRecursive(prj.ProjectItems).Where(i=>i.Name == block.FolderName).First();
}
else if (String.IsNullOrEmpty(block.FolderName) == false)
{
item = GetAllProjectItemsRecursive(
dte.ActiveDocument.ProjectItem.ContainingProject.ProjectItems).
Where(i=>i.Name == block.FolderName).First();
} if (item != null)
{
return GetProjectItemFullPath(item);
} return defaultPath;
}
public static string GetTemplatePlaceholderName(EnvDTE.ProjectItem item)
{
return String.Format("{0}.txt4", Path.GetFileNameWithoutExtension(item.Name));
} public static EnvDTE.ProjectItem GetTemplateProjectItem(EnvDTE.DTE dte, OutputFile file, EnvDTE.ProjectItem defaultItem)
{
if (String.IsNullOrEmpty(file.ProjectName) == true && String.IsNullOrEmpty(file.FolderName) == true)
{
return defaultItem;
} string templatePlaceholder = GetTemplatePlaceholderName(defaultItem);
string itemPath = Path.GetDirectoryName(file.FileName);
string fullName = Path.Combine(itemPath, templatePlaceholder);
EnvDTE.Project prj = null;
EnvDTE.ProjectItem item = null; if (String.IsNullOrEmpty(file.ProjectName) == false)
{
prj = GetProject(dte, file.ProjectName);
} if (String.IsNullOrEmpty(file.FolderName) == true && prj != null)
{
return FindProjectItem(prj.ProjectItems, fullName, true);
}
else if (prj != null && String.IsNullOrEmpty(file.FolderName) == false)
{
item = GetAllProjectItemsRecursive(prj.ProjectItems).Where(i=>i.Name == file.FolderName).First();
}
else if (String.IsNullOrEmpty(file.FolderName) == false)
{
item = GetAllProjectItemsRecursive(
dte.ActiveDocument.ProjectItem.ContainingProject.ProjectItems).
Where(i=>i.Name == file.FolderName).First();
} if (item != null)
{
return FindProjectItem(item.ProjectItems, fullName, true);
} return defaultItem;
} private static EnvDTE.ProjectItem FindProjectItem(EnvDTE.ProjectItems items, string fullName, bool canCreateIfNotExists)
{
EnvDTE.ProjectItem item = (from i in items.Cast<EnvDTE.ProjectItem>()
where i.Name == Path.GetFileName(fullName)
select i).FirstOrDefault();
if (item == null)
{
File.CreateText(fullName);
item = items.AddFromFile(fullName);
} return item;
} public static EnvDTE.Project GetProject(EnvDTE.DTE dte, string projectName)
{
return GetAllProjects(dte).Where(p=>p.Name == projectName).First();
} public static IEnumerable<EnvDTE.Project> GetAllProjects(EnvDTE.DTE dte)
{
List<EnvDTE.Project> projectList = new List<EnvDTE.Project>(); var folders = dte.Solution.Projects.Cast<EnvDTE.Project>().Where(p=>p.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder); foreach (EnvDTE.Project folder in folders)
{
if (folder.ProjectItems == null) continue; foreach (EnvDTE.ProjectItem item in folder.ProjectItems)
{
if (item.Object is EnvDTE.Project)
projectList.Add(item.Object as EnvDTE.Project);
}
} var projects = dte.Solution.Projects.Cast<EnvDTE.Project>().Where(p=>p.Kind != EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder); if (projects.Count() > )
projectList.AddRange(projects); return projectList;
} public static EnvDTE.ProjectItem GetProjectItemWithName(EnvDTE.ProjectItems items, string itemName)
{
return GetAllProjectItemsRecursive(items).Cast<ProjectItem>().Where(i=>i.Name == itemName).First();
} public static string GetProjectItemFullPath(EnvDTE.ProjectItem item)
{
if (item == null)
return null; return item.Properties.Item("FullPath").Value.ToString();
} public static IEnumerable<EnvDTE.ProjectItem> GetAllSolutionItems(EnvDTE.DTE dte)
{
List<EnvDTE.ProjectItem> itemList = new List<EnvDTE.ProjectItem>(); foreach (Project item in GetAllProjects(dte))
{
if (item == null || item.ProjectItems == null) continue; itemList.AddRange(GetAllProjectItemsRecursive(item.ProjectItems));
} return itemList;
} public static IEnumerable<EnvDTE.ProjectItem> GetAllProjectItemsRecursive(EnvDTE.ProjectItems projectItems)
{
foreach (EnvDTE.ProjectItem projectItem in projectItems)
{
if (projectItem.ProjectItems == null) continue; foreach (EnvDTE.ProjectItem subItem in GetAllProjectItemsRecursive(projectItem.ProjectItems))
{
yield return subItem;
} yield return projectItem;
}
}
} public sealed class OutputFile
{
public OutputFile()
{
this.FileProperties = new FileProperties
{
CustomTool = String.Empty,
BuildAction = BuildAction.None
};
} public string FileName { get; set; }
public string ProjectName { get; set; }
public string FolderName { get; set; }
public string Content { get; set; }
public FileProperties FileProperties { get; set; }
} public class BuildAction
{
public const string None = "None";
public const string Compile = "Compile";
public const string Content = "Content";
public const string EmbeddedResource = "EmbeddedResource";
public const string EntityDeploy = "EntityDeploy";
} public sealed class FileProperties
{
public FileProperties ()
{
this.TemplateParameter = new Dictionary<string,string>();
} public string CustomTool { get; set; }
public string BuildAction { get; set; }
public Dictionary<string, string> TemplateParameter { get; set; } internal string BuildActionString
{
get
{
return this.BuildAction;
}
}
} #>

最后注意如果允许TT模板提示dll错误,那就根据错误提示引用相应的dll就可以了

ahjesus使用T4模板自动维护实体的更多相关文章

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

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

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

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

  3. T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll

    生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 ,一定要自已新建,把T4代码复制进去,好多人因为用我现成的T4报错(原因不明) 点击添加文 ...

  4. 使用T4模板生成MySql数据库实体类

    注:本文系作者原创,但可随意转载. 现在呆的公司使用的数据库几乎都是MySQL.编程方式DatabaseFirst.即先写数据库设计,表设计按照规范好的文档写进EXCEL里,然后用公司的宏,生成建表脚 ...

  5. 关于PetaPoco的T4模板使用

    PetaPoco是一款适用于.Net 和Mono的微小.快速.单文件的微型ORM.PetaPoco介绍:http://www.cnblogs.com/youring2/archive/2012/06/ ...

  6. NFine框架的T4模板

    1.前言 前段时间在网上看到一个开源框架很好的.开源:ASP.NET MVC+EF6+Bootstrap开发框架,写代码就是比较比较麻烦,分层比较多,对于我这种偷懒的人就想到了写一个T4模板.不了解框 ...

  7. 一个基于DpperHelper的t4模板

    自定义模板,空的类(目的是和t4生成的模板分开,以免被覆盖) ExtensionDAL <#@ template debug="false" hostspecific=&qu ...

  8. T4模板使用

    本例使用的数据库是Northwind 1.新建tt文本模板customer.tt 2. 修改customer.tt内容为 <#@ template debug="false" ...

  9. T4模板使用记录,生成Model、Service、Repository

    自己目前在搭建一个.NET Core的框架,本来是打算使用前端做代码生成器直接生成到文件的,快做好了.感觉好像使用T4更方便一些,所以也就有了这篇文章~  我还是有个问题没解决,就是我想生成每个类(接 ...

随机推荐

  1. [转] 移动前端不得不了解的HTML5 head 头标签

    HTML的头部内容特别多,有针对SEO的头部信息,也有针对移动设备的头部信息.而且各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元 素,有很多差异性.移动端的工作已经越来越成为前端工作的重要内容 ...

  2. Sql Server 的本地时间和UTC时间

    一,本地时间和UTC时间 本地时间 世界的每个地区都有自己的本地时间,整个地球分为二十四时区,每个时区都有自己的本地时间. UTC时间 在国际无线电通信中,为统一而普遍使用一个标准时间,称为通用协调时 ...

  3. CSS实现点击事件及实践

    实现原理利用:target,把a标签自身的href以及id设置成一样的. 案例1:实现元素的切换 HTML: <div id="box"> <a href=&qu ...

  4. sublime简要笔记

    选中单词 [1]选中当前单词 ctrl+d [2]跳过当前单词 ctrl+k ctrl+d [3]选中相同的所有单词 alt+f3 [4]多行游标 按住shift,然后按住鼠标右键向下拖动 行操作 [ ...

  5. MemCache在win7上的可视化配置以及Nodejs/Net应用

    惯例科普:MemCache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要频繁访问数据库的 ...

  6. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  7. Concise - 面向对象的,一致的前端开发框架

    在当今世界,有许多前端开发的框架.那么,为什么还要再造一个框架呢?Concise 建立的目的是使你有很多的开箱即用的选项,让你能够方便的搭建移动友好的网站和 Web 应用程序.另外还包括一个简单的网格 ...

  8. [java] jsoup使用简介-汇率换算器实现-插曲2

    [java] jsoup使用简介-汇率换算器实现-插曲2 // */ // ]]>   [java] jsoup使用简介-汇率换算器实现-插曲2 Table of Contents 1 系列文章 ...

  9. 测试Servlet生命周期学习笔记

    测试环境:windows xp旗舰版 软件环境:myclipse8.5+tomcat7.0 ****************************************************** ...

  10. [logstash-input-file]插件使用详解

    前篇介绍过Logstash的使用,本篇继续深入,介绍下最常用的input插件——file. 这个插件可以从指定的目录或者文件读取内容,输入到管道处理,也算是logstash的核心插件了,大多数的使用场 ...