首先用T4模板生成对应的实体类。T4 代码。先建 EntityHelper.ttinclude ,Manager.ttinclude,ModelTemplate.tt。
EntityHelper.ttinclude 内容:
<#@ assembly name="$(ProjectDir)ExteriorBin\MySql.Data.dll" #>
<#@ assembly name="System.Data"#>
<#@ import namespace="System" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="MySql.Data.MySqlClient" #>
<#+
public class EntityHelper
{
public static List<Entity> GetEntities(string connectionString, List<string> databases)
{
var list = new List<Entity>();
var conn = new MySqlConnection(connectionString);
try
{
//LOWER(`information_schema`.`COLUMNS`.`TABLE_NAME`) LIKE '这里可以控制数据库表的过滤%' and
conn.Open();
var dbs = string.Join("','", databases.ToArray());
var cmd = string.Format(@"SELECT `information_schema`.`COLUMNS`.`TABLE_SCHEMA`
,`information_schema`.`COLUMNS`.`TABLE_NAME`
,`information_schema`.`COLUMNS`.`COLUMN_NAME`
,`information_schema`.`COLUMNS`.`DATA_TYPE`
,`information_schema`.`COLUMNS`.`COLUMN_COMMENT`
,`information_schema`.`COLUMNS`.`COLUMN_KEY`
FROM `information_schema`.`COLUMNS`
WHERE `information_schema`.`COLUMNS`.`TABLE_SCHEMA` IN ('{0}') ", dbs);
using (var reader = MySqlHelper.ExecuteReader(conn, cmd))
{
while (reader.Read())
{
var db = reader["TABLE_SCHEMA"].ToString();
var table = reader["TABLE_NAME"].ToString();
var column = reader["COLUMN_NAME"].ToString();
var type = reader["DATA_TYPE"].ToString();
var comment = reader["COLUMN_COMMENT"].ToString();
var pk=reader["COLUMN_KEY"].ToString();
var entity = list.FirstOrDefault(x => x.EntityName == table);
if(entity == null)
{
entity = new Entity(table);
entity.Fields.Add(new Field
{
Name = column,
Type = GetCLRType(type),
Comment = comment,
PKey=pk
});
list.Add(entity);
}
else
{
entity.Fields.Add(new Field
{
Name = column,
Type = GetCLRType(type),
Comment = comment,
PKey=pk
});
}
}
}
}
finally
{
conn.Close();
}
return list;
}
public static string GetCLRType(string dbType)
{
switch(dbType)
{
case "tinyint":
case "smallint":
case "mediumint":
case "int":
case "integer":
return "int?";
case "bigint":
return "System.Int64?";
case "double":
return "double?";
case "float":
return "float?";
case "decimal":
return "decimal?";
case "numeric":
case "real":
return "decimal?";
case "bit":
return "bool";
case "date":
case "time":
case "year":
case "datetime":
case "timestamp":
return "DateTime?";
case "tinyblob":
case "blob":
case "longblob":
case "mediumblob":
case "longblog":
case "binary":
case "varbinary":
return "byte[]";
case "char":
case "varchar":
case "tinytext":
case "text":
case "mediumtext":
case "longtext":
return "string";
case "point":
case "linestring":
case "polygon":
case "geometry":
case "multipoint":
case "multilinestring":
case "multipolygon":
case "geometrycollection":
case "enum":
case "set":
default:
return dbType;
}
}
}
public class Entity
{
public Entity()
{
this.Fields = new List<Field>();
}
public Entity(string name)
: this()
{
this.EntityName = name;
}
public string EntityName { get;set; }
public List<Field> Fields { get;set; }
}
public class Field
{
public string Name { get;set; }
public string Type { get;set; }
public string Comment { get;set; }
public string PKey { get;set; }
}
#>
ModelTemplate.tt内容:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ include file="Manager.ttinclude" #>
<#@ include file="EntityHelper.ttinclude" #>
<#
// 数据库连接
var connectionString = @"这里是连接数据库字符串";
// 需要解析的数据库
var database = new List<string> {"指定库名" };
// 文件版权信息
var copyright = DateTime.Now.Year + " Aero Enterprises All Rights Reserved";
var version = Environment.Version;
var author = "auto generated by T4";
var manager = Manager.Create(Host, GenerationEnvironment);
var entities = EntityHelper.GetEntities(connectionString, database);
foreach(Entity entity in entities)
{
string tableName=entity.EntityName;
string className=entity.EntityName;
//string[] str=entity.EntityName.Split('_');
//string[] str= new string[]{entity.EntityName};
//if(str.Length>0)
//{
// for(int i=0;i<str.Length;i++)
// {
// className+=str[i].Trim().Substring(0, 1).ToUpper();
// className+=str[i].Trim().Substring(1, str[i].Length-1).ToLower();
// }
//}
manager.StartNewFile(className + ".cs");
#>
//-----------------------------------------------------------------------
// <copyright file=" <#= className #>.cs" company="Aero">
// * Copyright (C) <#= copyright #>
// * version : <#= version #>
// * author : <#= author #>
// * FileName: <#= className #>.cs
// * history : Created by T4
// </copyright>
//-----------------------------------------------------------------------
using System;
using DataCommon;
namespace DataEntity.Mysql
{
/// <summary>
/// 数据表实体类:<#= className #>
/// </summary>
[TableName("<#= tableName #>")]
public class <#= className #>
{
<#
for(int i = 0; i < entity.Fields.Count; i++)
{
if(i ==0){
#>
<#if(entity.Fields[i].PKey=="PRI"){#>[PKey("<#=entity.Fields[i].Name#>")]<#}else{}#>
/// <summary>
/// <#= entity.Fields[i].Comment #>
/// </summary>
public <#= entity.Fields[i].Type #> <#= entity.Fields[i].Name #> { get; set; }
<#}
else{#>
<#if(entity.Fields[i].PKey=="PRI"){#>[PKey("<#=entity.Fields[i].Name#>")]<#}else{}#>
/// <summary>
/// <#= entity.Fields[i].Comment #>
/// </summary>
public <#= entity.Fields[i].Type #> <#= entity.Fields[i].Name #> { get; set; }
<#}
}
#>
}
}
<#
manager.EndBlock();
}
manager.Process(true);
#>
Manager.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"#>
<#@ import namespace="System.CodeDom"#>
<#@ import namespace="System.CodeDom.Compiler"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.Data.Linq"#>
<#@ import namespace="System.Data.Linq.Mapping"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Linq"#>
<#@ import namespace="System.Reflection"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Xml.Linq"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public String Name;
public int Start, Length;
}
private Block currentBlock;
private List<Block> files = new List<Block>();
private Block footer = new Block();
private Block header = new Block();
private ITextTemplatingEngineHost host;
private StringBuilder template;
protected 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) {
if (name == null)
throw new ArgumentNullException("name");
CurrentBlock = new Block { Name = name };
}
public void StartFooter() {
CurrentBlock = footer;
}
public void StartHeader() {
CurrentBlock = header;
}
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) {
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();
foreach(Block block in files) {
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);
}
}
}
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 EnvDTE.ProjectItem templateProjectItem;
private EnvDTE.DTE dte;
private Action<String> checkOutAction;
private Action<IEnumerable<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) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split);
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 = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
}
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
var keepFileNameSet = new HashSet<String>(keepFileNames);
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.get_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));
}
}
} #>
当然了你需要你想要的地方添加 Mysql的dll文件。在EntityHelper.ttinclude最上面一行需要找到Mysql的dll。不然会报错的。
现在直接Ctrl +s保存模板就会生成数据库的实体类。不管你数据库创多少表都直接ctrl s自动生成实体类了。
接下来就是在数据访问层用T4生成对应的上下文对象。
新建DbContextTemplate.tt ,EntitiesHelper.ttinclude,Manager.ttinclude文件。
DbContextTemplate.tt内容:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ include file="Manager.ttinclude" #>
<#@ include file="EntitiesHelper.ttinclude" #>
<#
// 数据库连接
var connectionString = @"数据库连接;";
// 需要解析的数据库
var database = new List<string> {"指定库" };
// 文件版权信息
var copyright = DateTime.Now.Year + " Aero Enterprises All Rights Reserved";
var version = Environment.Version;
var author = "auto generated by T4";
var manager = Manager.Create(Host, GenerationEnvironment);
var entities = EntityHelper.GetEntities(connectionString, database);
#>
<# manager.StartNewFile("Entities.cs");#>
//-----------------------------------------------------------------------
// <copyright file=" Entities.cs" company="Aero">
// * Copyright (C) <#= copyright #>
// * version : <#= version #>
// * author : <#= author #>
// * FileName: Entities.cs
// * history : Created by T4
// </copyright>
//-----------------------------------------------------------------------
using DataEntity;
using Microsoft.EntityFrameworkCore;
namespace DataBehavior
{
///ef上下文对象与实体维护
//[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]// mysql数据库需加此描述,否则去除
public class Entities : DbContext
{
public Entities(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
<#
string pk="";
foreach (Entity entity in entities)
{
//获取实体名称
string className1=entity.EntityName;
// string[] str=entity.EntityName.Split('_');
//if(str.Length>0)
//{
// for(int i=0;i<str.Length;i++)
// {
// className1+=str[i].Trim().Substring(0, 1).ToUpper();
// className1+=str[i].Trim().Substring(1, str[i].Length-1).ToLower();
// }
// }
pk="";
//拼接主键
for(int i = 0; i < entity.Fields.Count; i++)
{
if(entity.Fields[i].PKey=="PRI")
{
//pk+="p."+entity.Fields[i].Name.ToUpper()+",";
pk+="p."+entity.Fields[i].Name+",";
}
}
if(pk!=""){#>
modelBuilder.Entity<<#=className1#>>().HasKey(p => new { <#=pk.Substring(0, pk.Length-1)#> });
<#}else{#>
modelBuilder.Entity<<#=className1#>>();
<#}
}#>
}
<# foreach (Entity entity in entities)
{
//获取实体名称
string className1="";
//string[] str=entity.EntityName.Split('_');
//if(str.Length>0)
//{
// for(int i=0;i<str.Length;i++)
// {
// className1+=str[i].Trim().Substring(0, 1).ToUpper();
// className1+=str[i].Trim().Substring(1, str[i].Length-1).ToLower();
// }
// }
#>
public virtual DbSet<<#=entity.EntityName#>> <#=entity.EntityName#> { get; set; }
<#}#>}
}
<# manager.EndBlock(); #>
<# manager.Process(true); #>
EntitiesHelper.ttinclude内容:
<#@ assembly name="$(ProjectDir)ExteriorBin\MySql.Data.dll" #>
<#@ assembly name="System.Data"#>
<#@ import namespace="System" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="MySql.Data.MySqlClient" #>
<#+
public class EntityHelper
{
public static List<Entity> GetEntities(string connectionString, List<string> databases)
{
var list = new List<Entity>();
var conn = new MySqlConnection(connectionString);
try
{
// LOWER(`information_schema`.`COLUMNS`.`TABLE_NAME`) LIKE '过滤特定表不进行生成%' and
conn.Open();
var dbs = string.Join("','", databases.ToArray());
var cmd = string.Format(@"SELECT `information_schema`.`COLUMNS`.`TABLE_SCHEMA`
,`information_schema`.`COLUMNS`.`TABLE_NAME`
,`information_schema`.`COLUMNS`.`COLUMN_NAME`
,`information_schema`.`COLUMNS`.`DATA_TYPE`
,`information_schema`.`COLUMNS`.`COLUMN_COMMENT`
,`information_schema`.`COLUMNS`.`COLUMN_KEY`
FROM `information_schema`.`COLUMNS`
WHERE`information_schema`.`COLUMNS`.`TABLE_SCHEMA` IN ('{0}') ", dbs);
using (var reader = MySqlHelper.ExecuteReader(conn, cmd))
{
while (reader.Read())
{
var db = reader["TABLE_SCHEMA"].ToString();
var table = reader["TABLE_NAME"].ToString();
var column = reader["COLUMN_NAME"].ToString();
var type = reader["DATA_TYPE"].ToString();
var comment = reader["COLUMN_COMMENT"].ToString();
var pk=reader["COLUMN_KEY"].ToString();
var entity = list.FirstOrDefault(x => x.EntityName == table);
if(entity == null)
{
entity = new Entity(table);
entity.Fields.Add(new Field
{
Name = column,
Type = GetCLRType(type),
Comment = comment,
PKey=pk
});
list.Add(entity);
}
else
{
entity.Fields.Add(new Field
{
Name = column,
Type = GetCLRType(type),
Comment = comment,
PKey=pk
});
}
}
}
}
finally
{
conn.Close();
}
return list;
}
public static string GetCLRType(string dbType)
{
switch(dbType)
{
case "tinyint":
case "smallint":
case "mediumint":
case "int":
case "integer":
return "int?";
case "bigint":
return "System.Int64?";
case "double":
return "double";
case "float":
return "float";
case "decimal":
return "decimal";
case "numeric":
case "real":
return "decimal";
case "bit":
return "bool";
case "date":
case "time":
case "year":
case "datetime":
case "timestamp":
return "DateTime?";
case "tinyblob":
case "blob":
case "mediumblob":
case "longblog":
case "binary":
case "varbinary":
return "byte[]";
case "char":
case "varchar":
case "tinytext":
case "text":
case "mediumtext":
case "longtext":
return "string";
case "point":
case "linestring":
case "polygon":
case "geometry":
case "multipoint":
case "multilinestring":
case "multipolygon":
case "geometrycollection":
case "enum":
case "set":
default:
return dbType;
}
}
}
public class Entity
{
public Entity()
{
this.Fields = new List<Field>();
}
public Entity(string name)
: this()
{
this.EntityName = name;
}
public string EntityName { get;set; }
public List<Field> Fields { get;set; }
}
public class Field
{
public string Name { get;set; }
public string Type { get;set; }
public string Comment { get;set; }
public string PKey { get;set; }
}
#>
Manager.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"#>
<#@ import namespace="System.CodeDom"#>
<#@ import namespace="System.CodeDom.Compiler"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.Data.Linq"#>
<#@ import namespace="System.Data.Linq.Mapping"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Linq"#>
<#@ import namespace="System.Reflection"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Xml.Linq"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public String Name;
public int Start, Length;
}
private Block currentBlock;
private List<Block> files = new List<Block>();
private Block footer = new Block();
private Block header = new Block();
private ITextTemplatingEngineHost host;
private StringBuilder template;
protected 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) {
if (name == null)
throw new ArgumentNullException("name");
CurrentBlock = new Block { Name = name };
}
public void StartFooter() {
CurrentBlock = footer;
}
public void StartHeader() {
CurrentBlock = header;
}
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) {
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();
foreach(Block block in files) {
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);
}
}
}
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 EnvDTE.ProjectItem templateProjectItem;
private EnvDTE.DTE dte;
private Action<String> checkOutAction;
private Action<IEnumerable<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) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split);
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 = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
}
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
var keepFileNameSet = new HashSet<String>(keepFileNames);
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.get_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));
}
}
} #>
不要忘记在项目根据EntitiesHelper.ttinclude的最上面新建文件夹添加一个Mysql.dll文件。让它引用到。
下面Ctrl+s就会生成对应的所有实体类的上下文对象。
然后新建一个类。
public class BaseDataBehavior
{
public static Entities Db;
public BaseDataBehavior(Entities _context)
{
Db = _context;
}
}
定义一个数据访问层的公共的泛型通用实现类。 继承 BaseDataBehavior。就不一一写增删改查了。举个例子。以返回数据集合为例。
public class Common:BaseDataBehavior,ICommon
{
public Common(Entities context):base(context)
{
}
public List<T> SelectList<T>() where T : class
{
return Db.Set<T>().ToList();
}
}
定义 数据访问层的接口 ICommon :
public interface ICommon
{
List<T> SelectList<T>() where T : class;
}
定义业务逻辑层的接口 ICommon:
public interface ICommon
{
List<T> SelectList<T>() where T : class;
}
定义业务逻辑层的实现类 Common 继承业务逻辑层的接口 ICommon。
定义一个私有的接口变量,通过依赖注入把 数据访问层的接口注入到业务逻辑层。
public class Common : ICommon
{
private readonly IDataBehavior.ICommon common;
public Common(IDataBehavior.ICommon _common)
{
common = _common;
}
public List<T> SelectList<T>() where T : class
{
return common.SelectList<T>();
}
}
这样大概逻辑写完了,但是还没有实现依赖注入。下面这样
在项目的ui层找到 Startup修改ConfigureServices。 先把t4模板生成的上下文对象给 AddDbContext。然后初始化的时候再实现业务逻辑跟数据访问层的依赖。
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDiscoveryClient(Configuration);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<DataBehavior.Entities>(c => c.UseMySQL(Configuration.GetConnectionString("Conn")));
services.AddConfig();
}
建一个类。统一来管理接口跟实现的依赖。对应Startup 的ConfigureServices下的AddConfig
public static class ServiceCollectionExtension
{
internal static void AddConfig(this IServiceCollection services)
{
services.AddScoped<IDataBehavior.ICommon, DataBehavior.Common>();
services.AddScoped<IService.ICommon, Service.Common>();
}
}
到这里基本就结束了。因为是泛型。调用的时候传进去实体就可以进行增删改查操作了。比如这样:
var List = common.SelectList<admin_user>();
list就是表数据。
第一次写博客别喷我。我只是一个刚接触.net的菜鸡。