实体框架 6 - 是否可以仅为特定的 dbContext 添加命令拦截器

时间:2021-04-15 15:32:05

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

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

我只需要修改进入 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; }
}

1 个答案:

答案 0 :(得分:0)

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

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 => ...
}
相关问题