zoukankan      html  css  js  c++  java
  • 七色花基本权限系统(9)- 中途整理和完善

    不多说,完善一下。

    完善数据核心层

    在数据实体层(SF.Framework.Entity)中,我们以一级文件夹区分了不同数据库的数据实体,如下图:

    image

    也是因此,在数据核心层(SF.Framework.DataCore)中定义EF数据上下文(MasterEntityContext)时,特地以Master作为类前缀来进行区分,实体配置工厂(MasterConfigurationFactory)也是同样的处理。

    观察这2个类,简单有规则,完全可以用T4来自动生成。反射数据实体层,获取每个数据实体的命名空间的最后的名称(比如从S.Framework.Entity.Master获取Master),作为前缀去生成EF数据库上下文类和实体配置工厂类。

    就这么办。创建2个模板,分别作为EF数据库上下文模板和实体配置工厂模板。

    image

    数据库上下文模板:

      1 <#+
      2 // <copyright file="EntityContext.tt" company="">
      3 //  Copyright © . All Rights Reserved.
      4 // </copyright>
      5 
      6 public class EntityContext : CSharpTemplate
      7 {
      8     private string _prefixName;
      9 
     10     public EntityContext(string prefixName)
     11     {
     12         _prefixName = prefixName;
     13     }
     14 	public override string TransformText()
     15 	{
     16 		base.TransformText();
     17 #>
     18 
     19 using System;
     20 using System.Collections.Generic;
     21 using System.Linq;
     22 using System.Text;
     23 using System.Threading.Tasks;
     24 using System.Data.Entity;
     25 using System.Data.Entity.ModelConfiguration.Conventions;
     26 
     27 using S.Framework.DataCore.EntityFramework.ConfigurationFactories;
     28 
     29 namespace S.Framework.DataCore.EntityFramework.EntityContexts
     30 {
     31 	/// <summary>
     32     /// 数据库上下文
     33     /// </summary>
     34     public class <#= _prefixName #>EntityContext : System.Data.Entity.DbContext
     35     {
     36         /// <summary>
     37         /// 构造函数
     38         /// </summary>
     39         /// <param name="nameOrConnectionString">数据库名称或连接字符串。</param>
     40         public <#= _prefixName #>EntityContext(string nameOrConnectionString)
     41             : base(nameOrConnectionString)
     42         { }
     43 
     44         /// <summary>
     45         /// 模型配置重写
     46         /// </summary>
     47         /// <param name="modelBuilder">数据实体生成器</param>
     48         protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
     49         {
     50             // 禁用一对多级联删除
     51             modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
     52             // 禁用多对多级联删除
     53             modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
     54             // 禁用表名自动复数规则
     55             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
     56 
     57             <#= _prefixName #>ConfigurationFactory.ConfigurationsInit(modelBuilder.Configurations);
     58         }
     59     }
     60 }
     61 <#+
     62         return this.GenerationEnvironment.ToString();
     63 	}
     64 }
     65 #>
     66 
    数据库上下文模板

    实体配置工厂模板:

      1 <#+
      2 // <copyright file="ConfigurationFactory.tt" company="">
      3 //  Copyright © . All Rights Reserved.
      4 // </copyright>
      5 
      6 public class ConfigurationFactory : CSharpTemplate
      7 {
      8     private string _prefixName;
      9 
     10     public ConfigurationFactory(string prefixName)
     11     {
     12         _prefixName = prefixName;
     13     }
     14 	public override string TransformText()
     15 	{
     16 		base.TransformText();
     17 #>
     18 
     19 using System;
     20 using System.Collections.Generic;
     21 using System.Linq;
     22 using System.Text;
     23 using System.Threading.Tasks;
     24 using System.Data.Entity.ModelConfiguration.Configuration;
     25 
     26 using S.Utilities;
     27 
     28 namespace S.Framework.DataCore.EntityFramework.ConfigurationFactories
     29 {
     30 	/// <summary>
     31     /// 实体配置工厂类
     32     /// </summary>
     33     public static class <#= _prefixName #>ConfigurationFactory
     34     {
     35         /// <summary>
     36         /// 同步对象
     37         /// </summary>
     38         private static readonly object sync = new object();
     39 
     40         /// <summary>
     41         /// 唯一实例
     42         /// </summary>
     43         private static IEnumerable<IEntityConfiguration> singleton;
     44 
     45         /// <summary>
     46         /// 实体配置
     47         /// </summary>
     48         private static IEnumerable<IEntityConfiguration> Configurations
     49         {
     50             get
     51             {
     52                 if (singleton == null)
     53                 {
     54                     lock (sync)
     55                     {
     56                         if (singleton == null)
     57                         {
     58                             var types = typeof(IEntityConfiguration).GetSubClass().Where(w => !w.IsAbstract && w.Namespace.EndsWith("<#= _prefixName #>"));
     59 
     60                             singleton = types.Select(m => Activator.CreateInstance(m) as IEntityConfiguration);
     61                         }
     62                     }
     63                 }
     64 
     65                 return singleton;
     66             }
     67         }
     68 
     69         /// <summary>
     70         /// 初始化实体模型生成器
     71         /// </summary>
     72         /// <param name="configurations">实体模型生成器</param>
     73         public static void ConfigurationsInit(ConfigurationRegistrar configurations)
     74         {
     75             foreach (var configuration in Configurations)
     76             {
     77                 configuration.RegistTo(configurations);
     78             }
     79         }
     80     }
     81 }
     82 <#+
     83         return this.GenerationEnvironment.ToString();
     84 	}
     85 }
     86 #>
     87 
    实体配置工厂模板

    设计好模板之后,调整一下执行器文件的代码,就可以了。修改后的执行器代码如下:

      1 <#@ template language="C#" debug="True" #>
      2 <#@ assembly name="System.Core" #>
      3 <#@ output extension="cs" #>
      4 <#@ import namespace="System.IO" #>
      5 <#@ import namespace="System.Text" #>
      6 <#@ import namespace="System.Reflection" #>
      7 <#@ import namespace="System.Linq" #>
      8 <#@ import namespace="System.Collections.Generic" #>
      9 <#@ include file="T4Toolbox.tt" #>
     10 <#@ include file="Configuration.tt" #>
     11 <#@ include file="ConfigurationFactory.tt" #>
     12 <#@ include file="EntityContext.tt" #>
     13 <#
     14 
     15     string coreName = "S.Framework", projectName = coreName + ".DataCore", entityProjectName = coreName + ".Entity";
     16     string entityBaseModelName = entityProjectName + ".EntityBaseModel";
     17     string entityBaseModelNameForReflection = entityProjectName + ".EntityModelBaseForReflection";
     18     //当前完整路径
     19     string currentPath = Path.GetDirectoryName(Host.TemplateFile);
     20     //T4文件夹的父级文件夹路径
     21     string projectPath = currentPath.Substring(0, currentPath.IndexOf(@"T4"));
     22     //解决方案路径
     23     string solutionFolderPath = currentPath.Substring(0, currentPath.IndexOf(@"" + projectName));
     24 
     25     //加载数据实体.dll
     26     string entityFilePath = string.Concat(solutionFolderPath, ("\"+ entityProjectName +"\bin\Debug\" + entityProjectName + ".dll"));
     27     byte[] fileData = File.ReadAllBytes(entityFilePath);
     28     Assembly assembly = Assembly.Load(fileData);
     29     //反射出实体类,不知道为啥此处不能成功判定“是否继承EntityModelBaseForReflection类”
     30     //因此只能通过名称比较的方式来判定
     31     IEnumerable<Type> modelTypes = assembly.GetTypes().Where(m => m.IsClass && !m.IsAbstract && (m.BaseType.FullName.Equals(entityBaseModelName) || m.BaseType.FullName.Equals(entityBaseModelNameForReflection)));
     32 
     33     //循环实体类
     34     List<string> prefixNames = new List<string>();
     35     foreach (Type item in modelTypes)
     36     {
     37         //找 实体文件夹 名称
     38         string tempNamespace= item.Namespace, nameSpaceWithoutProjectName = tempNamespace.Substring(entityProjectName.Length);
     39         if(nameSpaceWithoutProjectName.IndexOf(".") != 0 || nameSpaceWithoutProjectName.LastIndexOf(".") > 0)
     40         { continue; }
     41 
     42         //是否直接继承实体基本类
     43         bool purity = item.BaseType.FullName.Equals(entityBaseModelNameForReflection);
     44         //实体所在的数据库标识名称
     45         string targetName = nameSpaceWithoutProjectName.Substring(1);
     46         if(!prefixNames.Any(a => a == targetName)){ prefixNames.Add(targetName); }
     47         //目标文件的路径和名称(嵌套Generate文件夹是为了标识T4生成的类文件)
     48         string fileName= targetName + @"Generate" + item.Name + "Configuration.cs";
     49 
     50         //配置文件
     51         string folderName= @"Configurations";
     52         Configuration configuration = new Configuration(item.Name, targetName, purity);
     53         configuration.Output.Encoding = Encoding.UTF8;
     54         string path = projectPath + folderName + fileName;
     55         configuration.RenderToFile(path);
     56     }
     57 
     58     foreach(string prefixName in prefixNames)
     59     {
     60         //配置工厂文件
     61         string fileName = prefixName + "ConfigurationFactory.Generate.cs";
     62         ConfigurationFactory configurationFactory = new ConfigurationFactory(prefixName);
     63         configurationFactory.Output.Encoding = Encoding.UTF8;
     64         string path = string.Format(@"{0}ConfigurationFactories", projectPath) + fileName;
     65         configurationFactory.RenderToFile(path);
     66 
     67         //数据库上下文文件
     68         fileName = prefixName + "EntityContext.Generate.cs";
     69         EntityContext entityContext = new EntityContext(prefixName);
     70         entityContext.Output.Encoding = Encoding.UTF8;
     71         path = string.Format(@"{0}EntityContexts", projectPath) + fileName;
     72         entityContext.RenderToFile(path);
     73     }
     74 #>
     75 
    执行器代码

    运行一下执行器,发现EF数据库上下文和实体配置工厂都自动创建了。此时可以删除旧的EF数据库上下文和实体配置工厂。文档结构目录如下图:

    image

    编译,重新登录一下试试,没问题就好。

    完善数据实现层

    同样的,在数据实现层(S.Framework.DataAchieve)中,数据库初始化操作类(MasterDatabaseInitializer)也可以用相同的做法来自动生成。

    创建2个模板文件,分别表示数据库初始化策略配置类模板和数据库初始化类模板,如下图:

    image

    数据库初始化策略配置模板:

      1 <#+
      2 // <copyright file="MigrateConfiguration.tt" company="">
      3 //  Copyright © . All Rights Reserved.
      4 // </copyright>
      5 
      6 public class MigrateConfiguration : CSharpTemplate
      7 {
      8     private string _prefixName;
      9 
     10     public MigrateConfiguration(string prefixName)
     11     {
     12         this._prefixName = prefixName;
     13     }
     14 
     15 	public override string TransformText()
     16 	{
     17 		base.TransformText();
     18 #>
     19 using System;
     20 using System.Collections.Generic;
     21 using System.Linq;
     22 using System.Text;
     23 using System.Threading.Tasks;
     24 using System.Data.Entity.Migrations;
     25 
     26 using S.Framework.DataCore.EntityFramework.EntityContexts;
     27 
     28 namespace S.Framework.DataAchieve.EntityFramework.Initializes
     29 {
     30 	/// <summary>
     31     /// <#= _prefixName #> 数据库迁移策略
     32     /// </summary>
     33     internal sealed class <#= _prefixName #>MigrateConfiguration : DbMigrationsConfiguration<<#= _prefixName #>EntityContext>
     34     {
     35         /// <summary>
     36         /// 构造方法
     37         /// </summary>
     38         public <#= _prefixName #>MigrateConfiguration()
     39         {
     40             //表示开启自动合并
     41             this.AutomaticMigrationsEnabled = true;
     42             //表示将导致数据丢失的合并也允许进行
     43             this.AutomaticMigrationDataLossAllowed = true;
     44         }
     45 
     46         /// <summary>
     47         /// 数据初始化
     48         /// </summary>
     49         /// <param name="context">数据库上下文</param>
     50         protected override void Seed(<#= _prefixName #>EntityContext context)
     51         {
     52             //<#= _prefixName #>DataInit.DataInit(context);
     53         }
     54     }
     55 }
     56 <#+
     57         return this.GenerationEnvironment.ToString();
     58 	}
     59 }
     60 #>
     61 
    数据库初始化策略配置模板

    数据库初始化模板:

      1 <#+
      2 // <copyright file="DatabaseInitializer.tt" company="">
      3 //  Copyright © . All Rights Reserved.
      4 // </copyright>
      5 
      6 public class DatabaseInitializer : CSharpTemplate
      7 {
      8     private string _prefixName;
      9 
     10     public DatabaseInitializer(string prefixName)
     11     {
     12         this._prefixName = prefixName;
     13     }
     14 
     15 	public override string TransformText()
     16 	{
     17 		base.TransformText();
     18 #>
     19 
     20 using System;
     21 using System.Collections.Generic;
     22 using System.Linq;
     23 using System.Text;
     24 using System.Threading.Tasks;
     25 using System.Data.Entity;
     26 
     27 using S.Framework.DataCore.EntityFramework.EntityContexts;
     28 
     29 namespace S.Framework.DataAchieve.EntityFramework.Initializes
     30 {
     31 	/// <summary>
     32     /// <#= _prefixName #> 数据库初始化操作类
     33     /// </summary>
     34     public class <#= _prefixName #>DatabaseInitializer
     35     {
     36         /// <summary>
     37         /// 设置数据库初始化策略
     38         /// </summary>
     39         /// <param name="migrate">是否合并(自动迁移)。若是,则会检查数据库是否存在,若不存在则创建,若存在则进行自动迁移。若否,则不进行初始化操作(这样能避开EF访问sys.databases检测数据库是否存在,项目稳定后可将参数设置为false)。</param>
     40         public void Initialize(bool migrate)
     41         {
     42             if (!migrate)
     43             {
     44                 System.Data.Entity.Database.SetInitializer<<#= _prefixName #>EntityContext>(null);
     45             }
     46             else
     47             {
     48                 System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion<<#= _prefixName #>EntityContext, <#= _prefixName #>MigrateConfiguration>(true));
     49             }
     50         }
     51     }
     52 }
     53 <#+
     54         return this.GenerationEnvironment.ToString();
     55 	}
     56 }
     57 #>
     58 
    数据库初始化模板

    设计好模板之后,调整一下执行器文件的代码,就可以了。修改后的执行器代码如下:

      1 <#@ template language="C#" debug="True" #>
      2 <#@ assembly name="System.Core" #>
      3 <#@ output extension="cs" #>
      4 <#@ import namespace="System.IO" #>
      5 <#@ import namespace="System.Text" #>
      6 <#@ import namespace="System.Reflection" #>
      7 <#@ import namespace="System.Linq" #>
      8 <#@ import namespace="System.Collections.Generic" #>
      9 <#@ include file="T4Toolbox.tt" #>
     10 <#@ include file="Repository.tt" #>
     11 <#@ include file="MigrateConfiguration.tt" #>
     12 <#@ include file="DatabaseInitializer.tt" #>
     13 <#
     14 
     15     string coreName = "S.Framework", projectName = coreName + ".DataAchieve", entityProjectName = coreName + ".Entity";
     16     string entityBaseModelName = entityProjectName + ".EntityBaseModel";
     17     string entityBaseModelNameForReflection = entityProjectName + ".EntityModelBaseForReflection";
     18     //当前完整路径
     19     string currentPath = Path.GetDirectoryName(Host.TemplateFile);
     20     //T4文件夹的父级文件夹路径
     21     string projectPath = currentPath.Substring(0, currentPath.IndexOf(@"T4"));
     22     //解决方案路径
     23     string solutionFolderPath = currentPath.Substring(0, currentPath.IndexOf(@"" + projectName));
     24 
     25     //加载数据实体.dll
     26     string entityFilePath = string.Concat(solutionFolderPath, ("\"+ entityProjectName +"\bin\Debug\" + entityProjectName + ".dll"));
     27     byte[] fileData = File.ReadAllBytes(entityFilePath);
     28     Assembly assembly = Assembly.Load(fileData);
     29     //反射出实体类,不知道为啥此处不能成功判定“是否继承EntityModelBaseForReflection类”
     30     //因此只能通过名称比较的方式来判定
     31     IEnumerable<Type> modelTypes = assembly.GetTypes().Where(m => m.IsClass && !m.IsAbstract && (m.BaseType.FullName.Equals(entityBaseModelName) || m.BaseType.FullName.Equals(entityBaseModelNameForReflection)));
     32 
     33     //循环实体类
     34     Dictionary<string, List<Type>> prefixModelTypes = new Dictionary<string, List<Type>>();//存储[数据库标识名称]和[实体类型集合]
     35     foreach (Type item in modelTypes)
     36     {
     37         //找 实体文件夹 名称
     38         string tempNamespace= item.Namespace, nameSpaceWithoutProjectName = tempNamespace.Substring(entityProjectName.Length);
     39         if(nameSpaceWithoutProjectName.IndexOf(".") != 0 || nameSpaceWithoutProjectName.LastIndexOf(".") > 0)
     40         { continue; }
     41 
     42         //是否直接继承实体基本类
     43         bool purity = item.BaseType.FullName.Equals(entityBaseModelNameForReflection);
     44         //实体所在的数据库标识名称
     45         string targetName = nameSpaceWithoutProjectName.Substring(1);
     46         List<Type> temp;
     47         if(prefixModelTypes.TryGetValue(targetName, out temp))
     48         {
     49             temp.Add(item);
     50         }
     51         else
     52         {
     53             temp = new List<Type>{ item };
     54             prefixModelTypes.Add(targetName, temp);
     55         }
     56 
     57         //目标文件的路径和名称(嵌套Generate文件夹是为了标识T4生成的类文件)
     58         string fileName= targetName + @"Generate" + item.Name + "Repository.cs";
     59         //仓储文件
     60         string folderName= @"Repositories";
     61         Repository repository = new Repository(item.Name, targetName);
     62         repository.Output.Encoding = Encoding.UTF8;
     63         string path = projectPath + folderName + fileName;
     64         repository.RenderToFile(path);
     65     }
     66 
     67     foreach(KeyValuePair<string, List<Type>> item in prefixModelTypes)
     68     {
     69         //数据库初始化策略配置文件
     70         string fileName = "/"+ item.Key +"/" + item.Key + "MigrateConfiguration.Generate.cs";
     71         MigrateConfiguration mc = new MigrateConfiguration(item.Key);
     72         mc.Output.Encoding = Encoding.UTF8;
     73         string path = string.Format(@"{0}Initializes", projectPath) + fileName;
     74         mc.RenderToFile(path);
     75 
     76         //数据库初始化类文件
     77         fileName = "/"+ item.Key +"/" + item.Key + "DatabaseInitializer.Generate.cs";
     78         DatabaseInitializer temp = new DatabaseInitializer(item.Key);
     79         temp.Output.Encoding = Encoding.UTF8;
     80         path = string.Format(@"{0}Initializes", projectPath) + fileName;
     81         temp.RenderToFile(path);
     82     }
     83 #>
     84 
    执行器文件

    T4执行后的文件结构目录如下图:

    image

    其中的MasterDataInit.cs是手动创建的,用来个性化地往数据库中添加指定初始数据:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading.Tasks;
      6 
      7 using S.Framework.DataCore.EntityFramework.EntityContexts;
      8 using S.Framework.Entity.Master;
      9 
     10 namespace S.Framework.DataAchieve.EntityFramework.Initializes
     11 {
     12     internal class MasterDataInit
     13     {
     14         internal static void DataInit(MasterEntityContext context)
     15         {
     16             //判断admin是否存在,若存在,不新增
     17             var dbSet = context.Set<SysUser>();
     18             if (!dbSet.Any(a => a.UserName == "admin"))
     19             {
     20                 var entity = new SysUser { ID = Guid.NewGuid().ToString(), UserName = "admin", Password = "123456", CreateDate = DateTime.Now, CreateUser = "admin" };
     21                 //将用户对象附加给数据库上下文(这仅仅是内存级别的操作)
     22                 dbSet.Add(entity);
     23                 //数据库上下文保存更改(提交变更到数据库执行)
     24                 context.SaveChanges();
     25             }
     26         }
     27     }
     28 }
     29 
    往数据库填充初始数据

    然后还需要修改MasterMigrateConfiguration.Generate.cs,在Seed中调用一下MasterDataInit的方法即可。

    编译,重新登录一下试试,没问题就好。

    统一数据库配置信息

    创建类库项目,名称S.Framework,定义一个数据库配置类(DatabaseConfig.cs):

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading.Tasks;
      6 
      7 using S.Utilities;
      8 
      9 namespace S.Framework
     10 {
     11     public class DatabaseConfig
     12     {
     13         /// <summary>
     14         /// web.config文件中数据库连接字符串的名称
     15         /// </summary>
     16         public static string ConnectionStringName = "matrixkey";
     17         /// <summary>
     18         /// 默认的数据库管道名称
     19         /// </summary>
     20         public static readonly string DefaultProviderName = "System.Data.SqlClient";
     21 
     22         private static string _connectioonString = string.Empty;
     23         private static string _providerName = string.Empty;
     24 
     25         /// <summary>
     26         /// 数据连接字符串
     27         /// </summary>
     28         public static string ConnectionString
     29         {
     30             get
     31             {
     32                 if (string.IsNullOrEmpty(_connectioonString))
     33                 {
     34                     string tempConnectionString = string.Empty, tempProviderName = string.Empty;
     35                     if (ConfigHelper.TryGetConnectionInfo(ConnectionStringName, out tempConnectionString, out tempProviderName))
     36                     {
     37                         _connectioonString = tempConnectionString;
     38                         _providerName = tempProviderName;
     39                     }
     40                 }
     41                 if (string.IsNullOrWhiteSpace(_connectioonString))
     42                 {
     43                     throw ExceptionHelper.ThrowConfigException("不存在名为“" + ConnectionStringName + "”的数据库连接信息,请检查web.config文件中的设置。");
     44                 }
     45                 return _connectioonString;
     46             }
     47         }
     48 
     49         /// <summary>
     50         /// 数据提供程序
     51         /// </summary>
     52         public static string ProviderName
     53         {
     54             get
     55             {
     56                 if (string.IsNullOrEmpty(_providerName))
     57                 {
     58                     _providerName = ConfigHelper.ProviderName(ConnectionStringName);
     59                 }
     60                 if (string.IsNullOrWhiteSpace(_providerName))
     61                 {
     62                     _providerName = DefaultProviderName;
     63                 }
     64                 return _providerName;
     65             }
     66         }
     67 
     68         /// <summary>
     69         /// 表示WEB应用程序在初次使用数据库时,是否自动合并/迁移数据库。该属性只在 <see cref="DataDriven"/> 值为 EntityFramework 时有效。
     70         /// 该属性配置项由 Web.config/configuration/appSettings/Database:Migrate 参数指定。
     71         /// </summary>
     72         public static bool IsMigrateDatabase
     73         {
     74             get
     75             {
     76                 string tempIsMigrateDatabase = string.Empty;
     77                 if (ConfigHelper.TryGetAppSettingInfo("Database:Migrate", out tempIsMigrateDatabase))
     78                 { }
     79                 return string.IsNullOrEmpty(tempIsMigrateDatabase) ? false : tempIsMigrateDatabase.ToBoolean(false);
     80             }
     81         }
     82     }
     83 }
     84 
    数据库配置类

    在Web.config/appSettings中增加配置参数:

      1 <!--表示WEB应用程序在初次使用数据库时,是否自动合并/迁移数据库。-->
      2 <add key="Database:Migrate" value="true" />

    然后就是使用定义的配置。

    让WebUI层引用S.Framework,然后把WebUI层中的Global.asax中的

      1 new MasterDatabaseInitializer().Initialize(true);

    修改成

      1 new MasterDatabaseInitializer().Initialize(S.Framework.DatabaseConfig.IsMigrateDatabase);

    让S.Framework.DataAchieve层引用S.Framework,然后修改BaseRepository.cs的构造方法,把

      1 this.Db = new MasterEntityContext("matrixkey");

    修改成

      1 this.Db = new MasterEntityContext(S.Framework.DatabaseConfig.ConnectionStringName);

    总结一下,这篇日志演示了3处整理:

    1、利用T4自动生成EF数据库上下文和实体配置工厂

    2、利用T4自动生成数据库初始化策略和初始化类

    3、统一配置数据库参数

    下个章节将演示仓储接口的创建。

    截止本章节,项目源码下载:点击下载(存在百度云盘中)

  • 相关阅读:
    linux设置网关修改ip
    Linux Source命令及脚本的执行方式解析
    ARM9 S3C2440 定时器中断
    Linux下配置静态IP地址,设置DNS和主机名
    s3c2440外部中断操作
    vmware中为虚拟机添加硬盘空间
    『SHELL』SHELL脚本执行方式
    WCF开发的几个频骤
    MyEclipse下Axis2插件的下载和安装
    WCF系列(二) 使用配置文件构建和使用WCF服务
  • 原文地址:https://www.cnblogs.com/matrixkey/p/5590777.html
Copyright © 2011-2022 走看看