从 IDbCommandInterceptor 的实现获取 DbContext

bpi*_*iec 5 c# entity-framework interceptor entity-framework-6

我正在使用一个IDbCommandInterceptor实现:

\n\n
public class MyInterceptor : IDbCommandInterceptor\n{\n    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)\n    {\n        var context = interceptionContext.DbContexts.FirstOrDefault();\n    }\n\n    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)\n    {\n    }\n\n    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)\n    {\n    }\n\n    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)\n    {\n    }\n\n    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)\n    {\n    }\n\n    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)\n    {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

以此注入:

\n\n
public class TestContext : System.Data.Entity.DbContext\n{\n    // \xe2\x80\xa6\n\n    public TestContext()\n        : base("TestConnectionString")\n    {\n        Database.SetInitializer<TestContext>(null);\n        DbInterception.Add(new MyInterceptor());\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

interceptionContext.DbContexts始终是空的。如何获取执行上下文的实例?是否可以?

\n

bpi*_*iec 5

这并没有完全回答我的问题,而是我在实体框架文档中找到的解释是最准确的:

\n\n
\n

值得注意的是,拦截上下文是尽力提供上下文信息。然而,在某些特殊情况下,您期望的某些信息可能不存在。这是因为 EF 的代码路径无法轻易更改,并且不包含可能预期的信息。例如,当 EF 调用提供程序时,提供程序不知道正在使用的 DbContext。如果 EF 之外的提供程序决定调用 ExecuteNonQuery,则可能会发生两种情况:

\n\n
    \n
  • 首先,提供者可以直接进行调用,完全避免 EF 拦截。(这是在 EF 级别而不是在堆栈中进行拦截的结果。如果拦截在堆栈中较低的位置,那就太好了,但不幸的是,这超出了 EF 团队的控制范围。)
  • \n
  • 如果提供者知道 EF 拦截,那么它可以通过 EF 拦截器调度 ExecuteNonQuery 调用。这意味着任何已注册的拦截器都将收到通知并可以采取适当的行动。这就是 SQL Server 和 SQL Server Compact 提供程序所做的事情。但是,即使提供程序执行此操作,所使用的 DbContext 也可能不会包含在拦截上下文中,因为提供程序对此一无所知,并且允许这样做的更改会破坏定义良好的提供程序 API。
  • \n
\n\n

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

\n
\n\n

我不知道我的情况如何 \xe2\x80\x9crare\xe2\x80\x9d 但也许我做错了什么\xe2\x80\xa6

\n

  • 我也在尝试研究这一点,我的结论是拦截是事后才想到的一大堆黑客行为。最大的问题是 DbInterception 是一个静态类,因此所有拦截都是跨 AppDomain 的全局拦截。您无法创建仅更改一个上下文的隔离级别的 IsolationLevelDbCommandInterceptor。同样,无法确保上下文仅添加一次。 (3认同)