从IDbCommandInterceptor的实现中获取DbContext

时间:2015-03-11 19:26:09

标签: c# entity-framework entity-framework-6 interceptor

我正在使用IDbCommandInterceptor实施:

public class MyInterceptor : IDbCommandInterceptor
{
    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        var context = interceptionContext.DbContexts.FirstOrDefault();
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }
}

注入:

public class TestContext : System.Data.Entity.DbContext
{
    // …

    public TestContext()
        : base("TestConnectionString")
    {
        Database.SetInitializer<TestContext>(null);
        DbInterception.Add(new MyInterceptor());
    }
}

(也在静态构造函数中尝试过)。

interceptionContext.DbContexts总是空的。如何获取执行上下文的实例?有可能吗?

1 个答案:

答案 0 :(得分:4)

这并不能完全回答我的问题,但我在Entity Framework documentation中找到的解释是最准确的:

  

值得注意的是,拦截上下文是提供上下文信息的最佳方法。但是,在某些极端情况下,您可能不会有某些信息。这是因为EF具有无法轻易更改的代码路径,并且不包含可能预期的信息。例如,当EF对提供者进行调用时,提供者不知道正在使用的DbContext。如果EF之外的那个提供者决定调用ExecuteNonQuery,那么可能会发生两件事:

     
      
  • 首先,提供商可以直接拨打电话,完全避免EF拦截。 (这是在EF级别进行拦截而不是在堆栈中进行拦截的结果。如果堆栈中的拦截较低,那将是很好的,但不幸的是,这不受EF团队的控制。)
  •   
  • 如果提供者知道EF拦截,那么它可以通过EF拦截器调度ExecuteNonQuery调用。这意味着任何已注册的拦截器都会被通知并且可以采取适当的行动。这就是SQL Server和SQL Server Compact提供程序的功能。但是,即使提供程序执行此操作,很可能正在使用的DbContext将不会包含在拦截上下文中,因为提供程序不知道它,并且允许这样做的更改将破坏定义良好的提供程序API。
  •   
     

幸运的是,这种情况很少见,对大多数应用程序来说可能不是问题。

我不知道我的情况是如何“罕见”但也许我做错了...