• C#简单构架之EF进行读写分离+多数据库(Mysql/SqlService)


    最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构

    表现层view

      主要提供Web、WebApi等表现层的解决方案

    公共层public

       主要提供项目公共类库,数据缓存基础方法等

    实体层model

       主要提供数据库映射模型,还有就是DDD领域操作模型

    数据层Db

       主要封装EF操作基础类

    数据服务层Service

       主要提供数据库操作服务、缓存操作服务

    数据接口服务层inface

       主要提供数据库操作服务接口、缓存操作服务接口

    1.首先是多数据库的支持,目前就支持mysql/sqlservice,如果需要添加更多的数据库支持,只需要再数据库操作类型上面添加即可

    /// <summary>
        /// 数据库类型
        /// </summary>
        public enum DbContextType : byte
        {
            SqlService = 1,
            MySql = 2
        }
    View Code

    分别对mysql/sqlservice的上下文操作进行封装

    /// <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
    /// <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上下文初始化只需要设置类型

     /// <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
    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

    通过上面多数据库的支持已经完成,下面进行读写分离,分别进行继承上述上下文操作

    /// <summary>
        ////// </summary>
        public class WriteSqlServiceContext : SqlServiceContext
        {
            public WriteSqlServiceContext() : base("") { }
        }
        /// <summary>
        ////// </summary>
        public class ReadSqlServiceContext : SqlServiceContext
        {
            public ReadSqlServiceContext() : base("") { }
        }
    View Code

    通过工厂类进行初始化

    /// <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即可

     <!--数据库配置(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

    最后进行测试

    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

    搞定,可能在代码上有点累赘,但是总算是可行的。

    如果有兴趣的朋友可以留下邮箱,然后发全代码一起研究,谢谢!

  • 相关阅读:
    纯JavaScripst的全选、全不选、反选 【转】
    Java 文件和byte数组转换
    nc命令使用详解
    mtr 命令详解
    Nginx主动检测方案---Tengine
    Apache相关安全设置
    tomcat APR的配置
    Vsftpd 配置详解
    FTP主动模式和被动模式的区别
    iptables配置详解
  • 原文地址:https://www.cnblogs.com/kq123321/p/7002054.html
Copyright © 2020-2023  润新知