微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

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

解决方法

如果您只想为特定的 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 => ...
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。