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

搞定,可能在代碼上有點累贅,但是總算是可行的。

如果有興趣的朋友可以留下郵箱,然后發全代碼一起研究,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM