【问题标题】:Entity Framework 6 - is it possible to add command interceptor only for specific dbContextEntity Framework 6 - 是否可以仅为特定的 dbContext 添加命令拦截器
【发布时间】:2021-04-15 15:32:05
【问题描述】:

我需要拦截特定上下文的所有查询,但我的拦截器会捕获来自其他上下文的查询,是否可以只为特定上下文注册它?

我只需要修改到 Oracle 数据库的查询,但是这个解决方案从与 mssql 数据库相关的上下文中捕获查询。 我还用 Autofac 注册了我的上下文。

有没有更好的方法在执行之前修改 EF6 生成的查询?

class OracleDbCommandInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
    }

    public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
    }

    public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }
}

这就是我的上下文的样子

public abstract class OracleDbContext : oracleDb
{
    static OracleDbContext()
    {
        DbInterception.Add(new OracleDbCommandInterceptor());
    }
}

这是由 edmx 生成的

public partial class oracleDb: DbContext
{
    public oracleDb()
        : base("name=oracleDb")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Employees> Employees { get; set; }
}

【问题讨论】:

    标签: c# .net oracle entity-framework-6 interceptor


    【解决方案1】:

    如果您只想为特定的 dbContextinstance 添加命令拦截器,您可以在传递给构造函数的标志上安装拦截器。

    public abstract class OracleDbContext : oracleDb
    {
        OracleDbContext(bool installInterceptor)
        {
            if(installInterceptor)
                DbInterception.Add(new OracleDbCommandInterceptor());
        }
    }
    

    这样创建的 OracleDbContext 实例将安装一个拦截器。

    using(OracleDbContext ctx = new OracleDbContext(true)) {
        // Query will be intercepted.
        IEnumerable<Enployee> employees = ctx.Employees.Where(e => ...
    }
    

    这样创建的 OracleDbContext 实例不会安装拦截器。

    using(OracleDbContext ctx = new OracleDbContext(false)) {
        // Query will not be intercepted.
        IEnumerable<Enployee> employees = ctx.Employees.Where(e => ...
    }
    

    【讨论】:

    • 这是否将拦截器与其他 DBContext 分开?
    • 只有您使用 installInterceptor = True 创建的 OracleDbContext 实例才会安装拦截器。
    • OP 肯定知道这一点。我对这个问题的印象是它正在拦截来自所有查询的调用,这意味着所有 DBContext 都知道拦截,或者 DBContext 包含对 Oracle 和其他数据库的引用。
    • 是的,我需要将它与其他上下文分开,比如连接到 mssql 数据库的上下文,这个解决方案仍然可以捕获所有查询,我也在使用 Autofac 来注册上下文
    猜你喜欢
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    相关资源
    最近更新 更多