C#简单构架之EF进行读写分离+多数据库Mysql/SqlServer
http://www.php361.com/index.php?c=index&a=view&id=3857 不建议用,太重的框架EF,仅仅参考一下别人的思路就好。
[导读]最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构表现层view 主要提供Web、WebApi等表现层的解决方案公共层public 主要提供项目公共类库,数据缓存基础方法等实体层model 主要提供数据 最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构 表现层view 主要提供Web、WebApi等表现层的解决方案 公共层public 主要提供项目公共类库,数据缓存基础方法等 实体层model 主要提供数据库映射模型,还有就是DDD领域操作模型 数据层Db 主要封装EF操作基础类 数据服务层Service 主要提供数据库操作服务、缓存操作服务 数据接口服务层inface 主要提供数据库操作服务接口、缓存操作服务接口 1.首先是多数据库的支持,目前就支持mysql/sqlservice,如果需要添加更多的数据库支持,只需要再数据库操作类型上面添加即可 [源码] view plain /// <summary> /// 数据库类型 /// </summary> public enum DbContextType : byte { SqlService = 1, MySql = 2 } View Code 分别对mysql/sqlservice的上下文操作进行封装 [源码] view plain /// <summary> /// MySql操作类 /// </summary> [DbConfigurationType(typeof(MySqlEFConfiguration))] public class MySqlContext : DbContext { public DbSet<Test> TestEntities { get; set; } /// <summary> /// 配置默认的字符串链接 /// </summary> public MySqlContext() : base("DefaultConnection") { } /// <summary> /// 自定义数据库链接 /// </summary> /// <param name="connenction"></param> public MySqlContext(string connenction) : base(connenction) { } /// <summary> /// 实体对应规则的映射配置 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(DbModelBuilder modelBuilder) { } } View Code [源码] view plain /// <summary> /// Sql数据库操作类 /// </summary> public class SqlServiceContext : DbContext { /// <summary> /// 配置默认的字符串链接 /// </summary> public SqlServiceContext() { } /// <summary> /// 自定义数据库链接 /// </summary> /// <param name="connenction"></param> public SqlServiceContext(string connenction) : base(connenction) { } /// <summary> /// 实体对应规则的映射配置 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(DbModelBuilder modelBuilder) { } } View Code 在view调用时候,进行ef上下文初始化只需要设置类型 [源码] view plain /// <summary> /// 数据库策略初始化类 /// </summary> public static class DBInitializer { public static DbContextType DbContextType { get; set; } /// <summary> /// 数据库初始化策略配置 /// </summary>` public static void Initialize(DbContextType ContextType) { string IsUsedWR = System.Configuration.ConfigurationManager.AppSettings["IsUsedWR"]; DbContextType = ContextType; ///获得数据库最后一个版本 // Database.SetInitializer<DBContextHelper>(new MigrateDatabaseToLatestVersion<DBContextHelper, DBConfiguration>()); if (ContextType == DbContextType.SqlService) { Database.SetInitializer(new MigrateDatabaseToLatestVersion<WriteSqlServiceContext, WriteSqlServiceDBConfiguration>()); if (IsUsedWR == "1") { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ReadSqlServiceContext, ReadSqlSqlServiceDBConfiguration>()); } else { Database.SetInitializer<ReadSqlServiceContext>(null); } } else { Database.SetInitializer(new MigrateDatabaseToLatestVersion<WriteMySqlContext, WriteMySqlDBConfiguration>()); if (IsUsedWR == "1") { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ReadMySqlContext, ReadMySqlDBConfiguration>()); } else { Database.SetInitializer<ReadMySqlContext>(null); } //Database.SetInitializer<WriteMySqlContext>(null); // Database.SetInitializer<ReadMySqlContext>(null); } // Database.SetInitializer<DBContextHelper>(null); ///删除原来数据库 重新创建数据库 //Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ContextHelper>()); // Database.SetInitializer<ContextHelper>(new DropCreateDatabaseIfModelChanges<ContextHelper>()); } } View Code [源码] view plain public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //Autofac //ContainerBuilder builder = new ContainerBuilder(); //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()); //IContainer container = builder.Build(); //DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //Autofac初始化过程 ContainerBuilder builder = new ContainerBuilder(); builder.RegisterControllers(System.Reflection.Assembly.GetExecutingAssembly());//注册mvc容器的实现 var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList(); builder.RegisterAssemblyTypes(assemblys.ToArray()).Where(t => t.Name.Contains("Service")).AsImplementedInterfaces(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //初始化数据库 DBInitializer.Initialize(DbContextType.MySql); } } View Code 通过上面多数据库的支持已经完成,下面进行读写分离,分别进行继承上述上下文操作 [源码] view plain /// <summary> /// 读 /// </summary> public class WriteSqlServiceContext : SqlServiceContext { public WriteSqlServiceContext() : base("") { } } /// <summary> /// 写 /// </summary> public class ReadSqlServiceContext : SqlServiceContext { public ReadSqlServiceContext() : base("") { } } View Code 通过工厂类进行初始化 [源码] view plain /// <summary> /// 上下文工厂类 /// </summary> public static class Contextfactory { /// <summary> /// 获取上下文 /// </summary> /// <returns></returns> public static DbContext GetContext(DbOpertionType OpertionType) { DbContextType ContextType = DBInitializer.DbContextType; if (ContextType == DbContextType.MySql) { if (OpertionType == DbOpertionType.Read) return new ReadMySqlContext(); else return new WriteMySqlContext(); } else { if (OpertionType == DbOpertionType.Read) return new ReadSqlServiceContext(); else return new WriteSqlServiceContext(); } } /// <summary> /// 获取上下文操作 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="OpertionType"></param> /// <returns></returns> public static TEntity CallContext<TEntity>(DbOpertionType OpertionType) where TEntity: DbContext { var DbContext = GetContext(OpertionType); return (TEntity)DbContext; } } View Code 最后配置webcofig即可 [源码] view plain <!--数据库配置(WriteMySqlConnection:读数据库,ReadMySqlConnection:写数据库 如果无需要进行 就配置IsUsedWR,2个链接都写写入库)--> <connectionStrings> <add name="WriteMySqlConnection" connectionString="data source=*; Initial Catalog=YK_Test_WriteDB ; uid=root; pwd=yk12345;Charset=utf8" providerName="MySql.Data.MySqlClient" /> <add name="ReadMySqlConnection" connectionString="data source=*; Initial Catalog=YK_Test_ReadDB ; uid=root; pwd=yk12345;Charset=utf8" providerName="MySql.Data.MySqlClient" /> </connectionStrings> <!--数据库读取分离配置--> <!--是否开启读写分离 1:开启 0:不开启--> <add key="IsUsedWR" value="1"/> View Code 最后进行测试 [源码] view plain public class TestController : Controller { private ITestService _TestServiceDb { get; set; } public TestController(ITestService TestServiceDb) { _TestServiceDb = TestServiceDb; } // GET: Test public ActionResult Index() { var result = _TestServiceDb.AddEntity(new Test() { ID=Guid.NewGuid(), Age=11, CreateTime=DateTime.Now, Name="Test" }); var NewResult = _TestServiceDb.GetEntityByID(result.ID); return View(); } } View Code 搞定,可能在代码上有点累赘,但是总算是可行的。