c# - transaction - Obteniendo DbContext de la implementación de IDbCommandInterceptor
setinitializer entity framework 6 (1)
Estoy usando una implementación de 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)
{
}
}
Inyectado por esto:
public class TestContext : System.Data.Entity.DbContext
{
// …
public TestContext()
: base("TestConnectionString")
{
Database.SetInitializer<TestContext>(null);
DbInterception.Add(new MyInterceptor());
}
}
(también probado en constructor estático).
Pero interceptionContext.DbContexts
siempre está vacío. ¿Cómo puedo obtener una instancia de ejecución de contexto? ¿Es posible?
Esto no responde completamente mi pregunta, pero la explicación que encontré en la documentación de Entity Framework fue la más precisa:
Vale la pena señalar que el contexto de interceptación es un mejor esfuerzo para proporcionar información contextual. Sin embargo, en algunos casos de esquina, es posible que la información que esperaría estar allí no esté allí. Esto se debe a que EF tiene rutas de código que no se pueden cambiar fácilmente y no incluyen información que podría esperarse. Por ejemplo, cuando EF realiza una llamada a un proveedor, el proveedor no tiene conocimiento del uso del DbContext. Si ese proveedor, fuera de EF, decide llamar a ExecuteNonQuery, entonces pueden ocurrir dos cosas:
- Primero, el proveedor puede realizar la llamada directamente, evitando por completo la intercepción EF. (Esto es una consecuencia de tener intercepción en el nivel EF en lugar de bajar en la pila. Sería fantástico si la interceptación fuera menor en la pila, pero desafortunadamente está fuera del control del equipo EF).
- Si el proveedor conoce la interceptación EF, puede enviar la llamada ExecuteNonQuery a través de interceptores EF. Esto significa que cualquier interceptor registrado será notificado y puede actuar de manera apropiada. Esto es lo que hacen los proveedores de SQL Server y SQL Server Compact. Sin embargo, incluso cuando un proveedor hace esto, es probable que el DbContext que se utiliza no se incluya en el contexto de interceptación porque el proveedor no tiene conocimiento de ello, y un cambio para permitir esto rompería las API de proveedor bien definidas.
Afortunadamente, este tipo de situación es rara y probablemente no sea un problema para la mayoría de las aplicaciones.
No sé cómo mi situación es "rara", pero tal vez estoy haciendo algo mal ...