MVC中使用T4模板
参考博文
http://www.cnblogs.com/heyuquan/archive/2012/07/26/2610959.html
图片释义
1、简单示例,对基本的模块标记

2、根据上图生成的类

网上大佬写的JuCheap项目中的T4模板
https://gitee.com/jucheap/projects
T4代码
<#@ template language="C#" debug="true" hostspecific="True"#>
<#@ include file="$(SolutionDir)JuCheap.Service\MultipleOutputHelper.ttinclude" #>
<#@ import namespace="System"#> <#
string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");
var files = System.IO.Directory.GetFiles(solutionsPath + @"\JuCheap.Entity", "*.cs"); var manager = Manager.Create(Host, GenerationEnvironment); //1.开始输出接口契约文件
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
var name = file.Name.Replace("Entity.cs",string.Empty);
var lowerName =name.ToLower();
//定义输出文件
manager.StartNewFile("I"+name+"Service.Partial.cs", string.Empty);
#> /*******************************************************************************
* Copyright (C) JuCheap.Com
*
* Author: dj.wong
* Create Date: <#=DateTime.Now#>
* Description: Automated building by service@JuCheap.com
*
* Revision History:
* Date Author Description
* 2017-08-02 dj.wong optimization
*********************************************************************************/ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using JuCheap.Service.Dto; namespace JuCheap.Service.Abstracts
{
/// <summary>
/// <#=name#>业务契约
/// </summary>
public partial interface I<#=name#>Service
{
/// <summary>
/// 添加<#=lowerName#>
/// </summary>
/// <param name="<#=lowerName#>"><#=lowerName#>实体</param>
/// <returns></returns>
bool Add(<#=name#>Dto <#=lowerName#>); /// <summary>
/// 批量添加<#=lowerName#>
/// </summary>
/// <param name="models"><#=lowerName#>集合</param>
/// <returns></returns>
bool Add(List<<#=name#>Dto> models); /// <summary>
/// 编辑<#=lowerName#>
/// </summary>
/// <param name="<#=lowerName#>">实体</param>
/// <returns></returns>
bool Update(<#=name#>Dto <#=lowerName#>); /// <summary>
/// 批量更新<#=lowerName#>
/// </summary>
/// <param name="<#=lowerName#>s"><#=lowerName#>实体集合</param>
/// <returns></returns>
bool Update(IEnumerable<<#=name#>Dto> <#=lowerName#>s); /// <summary>
/// 删除<#=lowerName#>
/// </summary>
/// <param name="id">Id</param>
/// <returns></returns>
bool Delete(int id); /// <summary>
/// 批量删除<#=lowerName#>
/// </summary>
/// <param name="exp">条件表达式</param>
/// <returns></returns>
bool Delete(Expression<Func<<#=name#>Dto, bool>> exp); /// <summary>
/// 获取单条符合条件的 <#=lowerName#> 数据
/// </summary>
/// <param name="exp">条件表达式</param>
/// <returns></returns>
<#=name#>Dto GetOne(Expression<Func<<#=name#>Dto, bool>> exp); /// <summary>
/// 查询符合调价的 <#=lowerName#>
/// </summary>
/// <param name="exp">过滤条件</param>
/// <param name="orderExp">排序条件</param>
/// <param name="isDesc">是否是降序排列</param>
/// <returns></returns>
List<<#=name#>Dto> Query<OrderKeyType>(Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true); /// <summary>
/// 分页获取<#=lowerName#>
/// </summary>
/// <param name="queryBase">QueryBase</param>
/// <param name="exp">过滤条件</param>
/// <param name="orderExp">排序条件</param>
/// <param name="isDesc">是否是降序排列</param>
/// <returns></returns>
ResultDto<<#=name#>Dto> GetWithPages<OrderKeyType>(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true); /// <summary>
/// 分页获取<#=lowerName#>
/// </summary>
/// <param name="queryBase">QueryBase</param>
/// <param name="exp">过滤条件</param>
/// <param name="orderBy">排序条件</param>
/// <param name="orderDir">是否是降序排列</param>
/// <returns></returns>
ResultDto<<#=name#>Dto> GetWithPages(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, string orderBy, string orderDir = "desc");
}
}
<#
// 结束输出文件
manager.EndBlock();
}
//2.开始生成契约实现文件
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
var name = file.Name.Replace("Entity.cs",string.Empty);
var lowerName = name.ToLower();
//定义输出文件
manager.StartNewFile(name+"Service.Partial.cs", string.Empty);
#> /*******************************************************************************
* Copyright (C) JuCheap.Com
*
* Author: dj.wong
* Create Date: <#=DateTime.Now#>
* Description: Automated building by service@JuCheap.com
*
* Revision History:
* Date Author Description
*
*********************************************************************************/ using System;
using System.Collections.Generic;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Linq.Expressions;
using EntityFramework.Extensions;
using AutoMapper;
using JuCheap.Core;
using JuCheap.Core.Extentions;
using JuCheap.Entity;
using JuCheap.Service.Dto;
using Mehdime.Entity; namespace JuCheap.Service.Abstracts
{
/// <summary>
/// <#=name#>业务契约
/// </summary>
public partial class <#=name#>Service : ServiceBase<<#=name#>Entity>, IDependency, I<#=name#>Service
{
#region 构造函数注册上下文
public IDbContextScopeFactory _dbScopeFactory {get;set;} //private readonly IDbContextScopeFactory _dbScopeFactory; //public <#=name#>Service(IDbContextScopeFactory dbScopeFactory)
//{
// _dbScopeFactory = dbScopeFactory;
//} #endregion #region I<#=name#>Service 接口实现 /// <summary>
/// 添加<#=lowerName#>
/// </summary>
/// <param name="dto"><#=lowerName#>实体</param>
/// <returns></returns>
public bool Add(<#=name#>Dto dto)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var entity = Mapper.Map<<#=name#>Dto, <#=name#>Entity>(dto);
dbSet.Add(entity);
var count = db.SaveChanges();
return count > 0;
}
} /// <summary>
/// 批量添加<#=lowerName#>
/// </summary>
/// <param name="dtos"><#=lowerName#>集合</param>
/// <returns></returns>
public bool Add(List<<#=name#>Dto> dtos)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var entities = Mapper.Map<List<<#=name#>Dto>, List<<#=name#>Entity>>(dtos);
dbSet.AddRange(entities);
return db.SaveChanges() > 0;
}
} /// <summary>
/// 编辑<#=lowerName#>
/// </summary>
/// <param name="dto">实体</param>
/// <returns></returns>
public bool Update(<#=name#>Dto dto)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var entity = Mapper.Map<<#=name#>Dto, <#=name#>Entity>(dto);
dbSet.AddOrUpdate(entity);
return db.SaveChanges() > 0;
}
} /// <summary>
/// 批量更新<#=lowerName#>
/// </summary>
/// <param name="dtos"><#=lowerName#>实体集合</param>
/// <returns></returns>
public bool Update(IEnumerable<<#=name#>Dto> dtos)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var entities = Mapper.Map<IEnumerable<<#=name#>Dto>, IEnumerable<<#=name#>Entity>>(dtos);
dbSet.AddOrUpdate(entities.ToArray());
return db.SaveChanges() > 0;
}
} /// <summary>
/// 删除<#=lowerName#>
/// </summary>
/// <param name="id">Id</param>
/// <returns></returns>
public bool Delete(int id)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db); var model = dbSet.FirstOrDefault(item => item.Id == id);
dbSet.Remove(model);
return db.SaveChanges() > 0;
}
} /// <summary>
/// 批量删除<#=lowerName#>
/// </summary>
/// <param name="exp">条件表达式</param>
/// <returns></returns>
public bool Delete(Expression<Func<<#=name#>Dto, bool>> exp)
{
using (var scope = _dbScopeFactory.Create())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>(); var models = dbSet.Where(where);
dbSet.RemoveRange(models);
return db.SaveChanges() > 0;
}
} /// <summary>
/// 获取单条符合条件的 <#=lowerName#> 数据
/// </summary>
/// <param name="exp">条件表达式</param>
/// <returns></returns>
public <#=name#>Dto GetOne(Expression<Func<<#=name#>Dto, bool>> exp)
{
using (var scope = _dbScopeFactory.CreateReadOnly())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>();
var entity = dbSet.AsNoTracking().FirstOrDefault(where); return Mapper.Map<<#=name#>Entity, <#=name#>Dto>(entity);
}
} /// <summary>
/// 查询符合调价的 <#=lowerName#>
/// </summary>
/// <param name="exp">过滤条件</param>
/// <param name="orderExp">排序条件</param>
/// <param name="isDesc">是否是降序排列</param>
/// <returns></returns>
public List<<#=name#>Dto> Query<OrderKeyType>(Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true)
{
using (var scope = _dbScopeFactory.CreateReadOnly())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>();
var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>();
var query = GetQuery(dbSet, where, order, isDesc);
var list = query.ToList();
return Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list);
}
} /// <summary>
/// 分页获取<#=name#>
/// </summary>
/// <param name="queryBase">QueryBase</param>
/// <param name="exp">过滤条件</param>
/// <param name="orderExp">排序条件</param>
/// <param name="isDesc">是否是降序排列</param>
/// <returns></returns>
public ResultDto<<#=name#>Dto> GetWithPages<OrderKeyType>(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, Expression<Func<<#=name#>Dto, OrderKeyType>> orderExp, bool isDesc = true)
{
using (var scope = _dbScopeFactory.CreateReadOnly())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>();
var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>();
var query = GetQuery(dbSet, where, order, isDesc); var query_count = query.FutureCount();
var query_list = query.Skip(queryBase.Start).Take(queryBase.Length).Future();
var list = query_list.ToList(); var dto = new ResultDto<<#=name#>Dto>
{
recordsTotal = query_count.Value,
data = Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list)
};
return dto;
}
} /// <summary>
/// 分页获取<#=name#>
/// </summary>
/// <param name="queryBase">QueryBase</param>
/// <param name="exp">过滤条件</param>
/// <param name="orderBy">排序条件</param>
/// <param name="orderDir">排序类型:desc(默认)/asc</param>
/// <returns></returns>
public ResultDto<<#=name#>Dto> GetWithPages(QueryBase queryBase, Expression<Func<<#=name#>Dto, bool>> exp, string orderBy, string orderDir = "desc")
{
using (var scope = _dbScopeFactory.CreateReadOnly())
{
var db = GetDb(scope);
var dbSet = GetDbSet(db);
var where = exp.Cast<<#=name#>Dto, <#=name#>Entity, bool>();
//var order = orderExp.Cast<<#=name#>Dto, <#=name#>Entity, OrderKeyType>();
var query = GetQuery(dbSet, where, orderBy, orderDir); var query_count = query.FutureCount();
var query_list = query.Skip(queryBase.Start).Take(queryBase.Length).Future();
var list = query_list.ToList(); var dto = new ResultDto<<#=name#>Dto>
{
recordsTotal = query_count.Value,
data = Mapper.Map<List<<#=name#>Entity>, List<<#=name#>Dto>>(list)
};
return dto;
}
} #endregion
}
}
<#
// 结束输出文件
manager.EndBlock();
}
#> <#
manager.StartNewFile("AutoMapperConfiguration.Partial.cs", string.Empty);
#> /*******************************************************************************
* Copyright (C) JuCheap.Com
*
* Author: dj.wong
* Create Date: 2015/8/7 11:12:12
* Description: Automated building by service@JuCheap.com
*
* Revision History:
* Date Author Description
*
*********************************************************************************/ using AutoMapper;
using JuCheap.Entity;
using JuCheap.Service.Dto; namespace JuCheap.Service
{
/// <summary>
/// AutoMapper 配置
/// </summary>
public partial class AutoMapperConfiguration
{
/// <summary>
/// 配置AutoMapper
/// </summary>
public static void Config()
{
<#
//1.开始输出接口契约文件
foreach (var filePath in files)
{
var file = new FileInfo(filePath);
var name = file.Name.Replace("Entity.cs",string.Empty);
var lowerName =name.ToLower();
//定义输出文件
#>
Mapper.CreateMap<<#=name#>Entity, <#=name#>Dto>();
Mapper.CreateMap<<#=name#>Dto, <#=name#>Entity>();
<#
}
#>
}
}
}
<#
// 结束输出文件
manager.EndBlock();
// 执行编译
manager.Process(true);
#>
引用的ttInclude代码
<#@ assembly name="System.Core"
#><#@ assembly name="System.Data.Linq"
#><#@ assembly name="EnvDTE"
#><#@ assembly name="System.Xml"
#><#@ assembly name="System.Xml.Linq"
#><#@ import namespace="System.Collections.Generic"
#><#@ import namespace="System.IO"
#><#@ import namespace="System.Text"
#><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
#><#+
// https://raw.github.com/damieng/DamienGKit
// http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public String Name;
public string FilePath;
public int Start, Length;
public bool IncludeInDefault;
} private Block currentBlock;
private readonly List<Block> files = new List<Block>();
private readonly Block footer = new Block();
private readonly Block header = new Block();
private readonly ITextTemplatingEngineHost host;
private readonly StringBuilder template;
protected readonly List<String> generatedFileNames = new List<String>(); public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
} public void StartNewFile(String name, string filePath) {
if (name == null)
throw new ArgumentNullException("name");
CurrentBlock = new Block { Name = name, FilePath = filePath };
} public void StartFooter(bool includeInDefault = true) {
CurrentBlock = footer;
footer.IncludeInDefault = includeInDefault;
} public void StartHeader(bool includeInDefault = true) {
CurrentBlock = header;
header.IncludeInDefault = includeInDefault;
} public void EndBlock() {
if (CurrentBlock == null)
return;
CurrentBlock.Length = template.Length - CurrentBlock.Start;
if (CurrentBlock != header && CurrentBlock != footer)
files.Add(CurrentBlock);
currentBlock = null;
} public virtual void Process(bool split, bool sync = true) {
if (split) {
EndBlock();
String headerText = template.ToString(header.Start, header.Length);
String footerText = template.ToString(footer.Start, footer.Length);
String outputPath = Path.GetDirectoryName(host.TemplateFile);
files.Reverse();
if (!footer.IncludeInDefault)
template.Remove(footer.Start, footer.Length);
foreach(Block block in files) {
String myPath = block.FilePath;
if(!string.IsNullOrWhiteSpace(myPath))
outputPath = myPath;
String fileName = Path.Combine(outputPath, block.Name);
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
generatedFileNames.Add(fileName);
CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
}
if (!header.IncludeInDefault)
template.Remove(header.Start, header.Length);
}
} protected virtual void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content))
File.WriteAllText(fileName, content);
} public virtual String GetCustomToolNamespace(String fileName) {
return null;
} public virtual String DefaultProjectNamespace {
get { return null; }
} protected bool IsFileContentDifferent(String fileName, String newContent) {
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
} private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
this.host = host;
this.template = template;
} private Block CurrentBlock {
get { return currentBlock; }
set {
if (CurrentBlock != null)
EndBlock();
if (value != null)
value.Start = template.Length;
currentBlock = value;
}
} private class VSManager: Manager {
private readonly EnvDTE.ProjectItem templateProjectItem;
private readonly EnvDTE.DTE dte;
private readonly Action<String> checkOutAction;
private readonly Action<List<String>> projectSyncAction; public override String DefaultProjectNamespace {
get {
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
}
} public override String GetCustomToolNamespace(string fileName) {
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
} public override void Process(bool split, bool sync) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split, sync);
if (sync)
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
} protected override void CreateFile(String fileName, String content) {
if (IsFileContentDifferent(fileName, content)) {
CheckoutFileIfRequired(fileName);
File.WriteAllText(fileName, content);
}
} internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
: base(host, template) {
var hostServiceProvider = (IServiceProvider)host;
if (hostServiceProvider == null)
throw new ArgumentNullException("Could not obtain IServiceProvider");
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);
checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames);
} private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List<String> keepFileNames) {
var keepFileNameSet = new HashSet<String>(keepFileNames);
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + ".";
foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.FileNames[0], projectItem); // Remove unused items from the project
foreach (var pair in projectFiles)
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
pair.Value.Delete(); // Add missing files to the project
foreach(String fileName in keepFileNameSet)
if (!projectFiles.ContainsKey(fileName))
templateProjectItem.ProjectItems.AddFromFile(fileName);
} private void CheckoutFileIfRequired(String fileName) {
var sc = dte.SourceControl;
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}
}
} #>
用到的语法:
1、string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");
T4模板中获取当前解决方案的文件路径。
2、var files = System.IO.Directory.GetFiles(solutionsPath + @"\JuCheap.Entity", "*.cs");
获取JuCheap.Entity项目中所有cs扩展名的文件信息。
3、var manager = Manager.Create(Host, GenerationEnvironment);
在引用的ttInclude中,创建一个模板管理者的对象,用于操作和生成数据。
4、 public partial interface I<#=name#>Service
在<# string name="ClassName" #> 中声明的变量,
可以在文本块中以<#=name#>的形式调用。(name为声明的变量名称)
5、 manager.EndBlock();
在引用的ttInclude中,结束对新服务类的内容赋值,
将文件对象添加到文件集合中。
6、manager.Process(true);
在引用的ttInclude中,结束数据生成,编译运行,生成相应的文件。
总结
因为有CodeSmith的使用经验,所以在看到T4模板使用方法时,
没有想象的那么困难。
纸上得来终觉浅,绝知此事要躬行。
目前只是看网上大佬的教程,还没有在项目中实际使用过,
还有许多未知的问题和操作。
MVC中使用T4模板的更多相关文章
- ASP.NET MVC 中的 T4
		
每次使用“添加视图”或“添加控制器”功能时,您都在 ASP.NET MVC 项目中使用 T4 模板.这些模板位于 Common7\IDE\ItemTemplates\CSharp\Web\MVC 2\ ...
 - RazorEngine.Templating MVC中View当模板
		
最近在做一个生成JSON的功能,比较笨的办法就是把需要的数据拆分开,保存到数据库,在从数据库中取出来进行拼接.这种方法比较笨,代码就不贴了. 需要注意拼接的时的转义字符: "\"s ...
 - Asp.Net MVC中使用ACE模板之Jqgrid
		
第一次看到ACE模板,有种感动,有种相见恨晚的感觉,于是迅速来研究.它本身是基于bootstrap和jqueryui,但更nice,整合之后为后台开发节省了大量时间. 发现虽然不是完美,整体效果还是不 ...
 - MVC中在RAZOR 模板里突然了现了 CANNOT RESOLVE SYMBOL ‘VIEWBAG’ 的错误提示
		
然后在Razor中出现了@ViewBag的不可用,@Url不可用,@Html 这些变量都不能用了. 异常提示: 编译器错误消息: CS0426: 类型“XX.Model.System”中不存在类型名称 ...
 - Asp.Net T4模板生成三层架构
		
1.T4 Editor安装 T4:根据模板生成文件,例如model等 vs中默认t4模板编码是没有提示和高亮的,需使用以下插件,免费的 https://t4-editor.tangible-engin ...
 - MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码
		
前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少代码相似度较高,比如负责实体映射的 EntityConfiguration,负责仓储操作的I ...
 - T4 模板 : 一种提升ASP.NET MVC开发速度方法
		
最近由于需要在框架中提供一些自定义模板的功能,找到了一篇博客,可惜似乎是翻译工具直接翻的,读不通顺,就试着自己翻译下,我不会完全翻译原文的句子,可能会对原文进行小范围的我认为更合适的句子并添加些注释, ...
 - ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板
		
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
 - [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码
		
本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...
 
随机推荐
- sublime text3配置javascript运行环境
			
步骤一 安装node.js 官网下载链接:node.js 步骤二 Sublime 依次点击 菜单栏 Tools => Build System => New Build System 步骤 ...
 - C语言讲义——C语言的布尔类型
			
C89标准中没有定义布尔类型: C99中增加了_Bool类型.实际上是只能等于0或1的整数类型,凡是不为0的整数都被转变为1, C99还提供了一个头文件<stdbool.h>,该头文件提供 ...
 - 用Python爬取英雄联盟(lol)全部皮肤
			
小三:"怎么了小二?一副无精打采的样子!" 小二:"唉!别提了,还不是最近又接触了一个叫英雄联盟的游戏,游戏中很多皮肤都需要花钱买,但是我钱不够呀..." 小三 ...
 - centos xargs
			
有些时候过滤后的东西需要传递给后面其它命令执行实现需求,这个时候xargs就派上用场了. 比如我想把过滤后的东东拷贝至其它目录,其实我可以进入那个目录然后执行ls,然后是过滤,接着再手工以拷贝那样也可 ...
 - Spring中的Mybatis
			
1. 前言 在构建一个web应用时基本的套路就是SSM,其中的M就是Mybatis. Mybatis作为一款开源的ORM框架, 由于其易于上手的特点成为当下比较流行的ORM框架,当然它还有一款插件能够 ...
 - 饱含辛酸开发 WPF CustomControl
			
引言 不知不觉间WPF开发已有两年光景,或许有很多人会问WPF还需要学习吗?WPF还有前途吗?其实我也很担心这个问题. .Net Core3.x已经支持WPF开发,.Net 5也宣布要支持WPF.是否 ...
 - Linu之用户管理【useradd】【userdel】【usermod】【passwd】【权限】
			
linux下创建用户 1.用户的创建 • 简介 linux是一个多用户多任务的分时操作系统,每个用户都是在root下的一个子用户,拥有不同的权限.用户登入成功后可进入系统和自己的主目录. •实现账号的 ...
 - 禅道的bug提交
 - vue绑定用户页面
			
1.vue微博回调空页面 微博回调空页面为: http://127.0.0.1:8888/oauth/callback/ 1.1 页面路径 components\oauth.vue <templ ...
 - python实现自动发邮件
			
Python有两个内置库:smtplib和email,可以实现邮件功能,无需下载,直接import导入. smtplib库负责发送邮件 Email库负责构造邮件格式和内容 邮件发送需要遵守SMTP协议 ...