EF6.0新特性-DbCommandInterceptor实现非SQL端读写分离

前几天看了一个基于sqlserver的负载均衡与读写分离的软件Moebius,实现的方式还是不错的,这使得用sqlserver数据库的同学时有机会对数据库进行更有效的优化了

看着人有做的东西,自己也想用EF来实现一个读写分离,所以就有了本篇文章,仓储大叔读写分离的思路是:

1  用sqlserver自带的发布、订阅实现主,从数据库的结构,同步这事由sql帮我们完成

2  配置文件建立几个供只读的数据库连接串

3  建立SQL命令拦截器

4  修改大叔的DbContextRepository基数,添加拦截行为

5  测试,搞定

有了上面的想法,咱就可以干事了,第一步不用说了,可以自己百度,从第2步说起

配置文件建立几个供只读的数据库连接串

<!-- 只写-->
    <add name="backgroundEntities" connectionString="metadata=res://*/background.csdl|res://*/background.ssdl|res://*/background.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=background;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
    <!-- 只读-->
    <add name="backgroundEntitiesRead" connectionString="metadata=res://*/background.csdl|res://*/background.ssdl|res://*/background.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />

  

建立SQL命令拦截器

/// <summary>
    /// SQL命令拦截器
    /// </summary>
    public class NoLockInterceptor : DbCommandInterceptor
    {
        private static readonly Regex _tableAliasRegex =
            new Regex(@"(?<tableAlias>AS \[Extent\d+\](?! WITH \(NOLOCK\)))",
                RegexOptions.Multiline | RegexOptions.IgnoreCase);

        [ThreadStatic]
        public static bool SuppressNoLock;
        public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            string conn = command.Connection.ConnectionString;
            base.NonQueryExecuting(command, interceptionContext);
        }
        public override void ScalarExecuting(DbCommand command,
            DbCommandInterceptionContext<object> interceptionContext)
        {
            command.Connection.Close();
            command.Connection.ConnectionString = "data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework";
            command.Connection.Open();

            if (!SuppressNoLock)
            {
                command.CommandText =
                    _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
            }
        }

        public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            command.Connection.Close();
            command.Connection.ConnectionString = "data source=.;initial catalog=background_Read1;persist security info=True;user id=sa;password=zzl123;multipleactiveresultsets=True;application name=EntityFramework";
            command.Connection.Open();
            if (!SuppressNoLock)
            {
                command.CommandText =
                    _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
            }
        }
    }

  

修改大叔的DbContextRepository基数,添加拦截行为

public DbContextRepository(IUnitOfWork db, Action<string> logger)
        {
            UnitWork = db;
            Db = (DbContext)db;
            Logger = logger;
            ((IObjectContextAdapter)Db).ObjectContext.CommandTimeout = 0;

            //SQL语句拦截器
            System.Data.Entity.Infrastructure.Interception.DbInterception.Add(new EntityFrameworks.Data.Core.Common.NoLockInterceptor());
            EntityFrameworks.Data.Core.Common.NoLockInterceptor.SuppressNoLock = true;
        }

  

大功造成,感谢阅读!

原文链接1:

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离

原文链接2:

基于 EntityFramework 的数据库主从读写分离服务插件

时间: 2024-10-19 12:43:33

EF6.0新特性-DbCommandInterceptor实现非SQL端读写分离的相关文章

Spark1.0.0新特性

Spark1.0.0 release于2014-05-30日正式公布,标志Spark正式进入1.X的时代.Spark1.0.0带来了各种新的特性,并提供了更好的API支持:Spark1.0.0添加了Spark SQL这一个新的重要组件,用于载入和操作Spark的结构化数据:Spark1.0.0增强了现有的标准库(ML,streaming,GraphX),同一时候还增强了Java和Python语言的支持:最后,Spark1.0.0在运维上做了非常大的改进,包含支持Hadoop/YARN安全机制.使

Mysql 8.0 新特性测试

Mysql 8.0 新特性测试 Role MySQL8.0版本添加了role特性,role是一种逻辑概念是权限的集合,可以将一个或以上的权限赋予给role,再将role赋给user.Oracle,Postgresql和Mariadb中早已存在role这个特性. create role role_test; grant select,insert,delete,update on zhongwc.tab01 to role_test; create user 'user1'@'%' identif

MySQL8.0新特性【转】

Server层,选项持久化 mysql> show variables like '%max_connections%'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | max_connections | 512 | | mysqlx_max_connections | 100 | +------------------------+-------

极速开发,快就是这么任性,你不知道的Jfinal2.0新特性

#Jfinal2.0新特性初探 **Jfinal2.0发布了,我认为这个是里程碑式的发布,新加了不少好功能,这个博文主要是写个那些不想看文档,又想知道Jfinal2.0到底有什么新变动的同学们的,希望你们看完以后,会更加认识Jfinal** ####只要拦截器做的好,没有AOP干不倒 ##Interceptor重现江湖 ###Interceptor细微变化1 ``` public class DemoInterceptor implements Interceptor { public void

C# 7.0 新特性3: 模式匹配

本文参考Roslyn项目Issue:#206,及Docs:#patterns. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 模式匹配也许能算的上C#本次更新最重量级的升级,也是最受关注的特性(也许没有之一),通过模式匹配,我们可以简化大量的条件代码. Switch语句 大家也许遇到过这样的情景,假设你的代码中,有一个Nullable<int>的值,需要对其在正整数,非正整数,Null三种情

C# 2.0 新特性(上)

C# 2.0新特性 1. 泛型 1.1 泛型介绍 泛型类和泛型方法同时具备可重用性.类型安全和效率,这是非泛型类和非泛型方法无法具备的.泛型通常用在集合和在集合上运行的方法中..NET Framework 2.0 版类库提供一个新的命名空间 System.Collections.Generic,其中包含几个新的基于泛型的集合类.建议面向 2.0 版的所有应用程序都使用新的泛型集合类,而不要使用旧的非泛型集合类,如 ArrayList.有关更多信息,请参见 .NET Framework 类库中的泛

[转]Servlet 3.0 新特性详解

原文地址:http://blog.csdn.net/xiazdong/article/details/7208316 Servlet 3.0 新特性概览 1.Servlet.Filter.Listener无需在web.xml中进行配置,可以通过Annotation进行配置: 2.模块化编程,即将各个Servlet模块化,将配置文件也分开配置. 3.Servlet异步处理,应对复杂业务处理: 4.异步Listener,对于异步处理的创建.完成等进行监听: 5. 文件上传API简化: tomcat

ASP.NET4.0新特性

原文:ASP.NET4.0新特性 在以前试用VS2010的时候已经关注到它在Web开发支持上的一些变化了,为此我还专门做了一个ppt,当初是计划在4月12日那天讲的,结果因为莫名其妙的原因导致没有语音以致放弃在LiveMeeting上的这次讲课,也导致了本篇的产生. 新增了项目模板 在创建Web项目时可以看到增加了更多的Web项目模板在VS2008中对应的情况如下: 在新模板中有如下改进:基础MemberShip功能.在大多数网站和应用程序中需要进行认证,因此在新模板中增加了认证功能使得用户能在

Java基础加强-(注解,类加载器,servlet3.0新特性)

1.   Annotation注解 1.1.  Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annotation就是提供了一种为程序元素设置元数据的方法,可用于修饰包.类.构造器.方法.成员变量.参数和局部变量的声明,这些信息被存储在Annotation的“name=value”对中. Annotation能被用来为程序元素(类.方法.成员变量等)设置元数据,比如一段代码的作者或者告诉编译器禁止一些特