Saltar al contenido

¿Puedo configurar un interceptor en EntityFramework Core?

Solución:

Actualización: la interceptación de las operaciones de la base de datos ahora está disponible en EF Core 3.0.

Respuesta original:


EF Core aún no tiene “interceptores” ni enlaces de ciclo de vida similares. Esta función se rastrea aquí: https://github.com/aspnet/EntityFramework/issues/626.

Es posible que no sea necesario anular un componente de bajo nivel si todo lo que desea es la salida del registro. Muchos componentes de EF Core de bajo nivel ya producen registros, registros que incluyen la ejecución de consultas. Puede configurar EF para usar una fábrica de registradores personalizados llamando DbContextOptionsBuilder.UseLoggerFactory(ILoggerFactory factory). (Consulte https://docs.asp.net/en/latest/fundamentals/logging.html y https://github.com/aspnet/Logging para obtener más detalles sobre esta interfaz de registrador). EF Core produce algunos eventos de registro notables con ID de eventos bien definidos. (Ver Microsoft.EntityFrameworkCore.Infrastructure.CoreLoggingEventId en 1.0.0-rc2, que se renombró simplementeMicrosoft.EntityFrameworkCore.Infrastructure.CoreEventId para 1.0.0 RTM.) Consulte https://docs.efproject.net/en/latest/misiverse/logging.html para ver ejemplos de cómo hacer esto.

Si necesita un registro adicional más allá de lo que ya producen los componentes de EF Core, deberá anular los componentes de nivel inferior de EF Core. La mejor forma de hacerlo es anulando el componente existente y agregando esta versión de anulación a EF a través de la inyección de dependencia. Hacer esto requiere configurar un proveedor de servicios personalizado para que EF lo use internamente. Esto está configurado por DbContextOptionsBuilder.UseInternalServiceProvider(IServiceProvider services) Consulte https://docs.efproject.net/en/latest/mis Miscellaneous/internals/services.html para obtener más detalles sobre cómo EF usa los servicios internamente.

Aquí hay un ejemplo encontrado en github de ajcvickers sobre cómo usar un Interceptor en EF CORE (2.2 al momento de responder esta pregunta):

public class NoLockInterceptor : IObserver<KeyValuePair<string, object>>
{
    public void OnCompleted()
    {
    }

    public void OnError(Exception error)
    {
    }

    public void OnNext(KeyValuePair<string, object> value)
    {
        if (value.Key == RelationalEventId.CommandExecuting.Name)
        {
            var command = ((CommandEventData)value.Value).Command;

            // Do command.CommandText manipulation here
        }
    }
}

A continuación, cree un oyente global para los diagnósticos de EF. Algo como:

public class EfGlobalListener : IObserver<DiagnosticListener>
{
    private readonly NoLockInterceptor _noLockInterceptor = new NoLockInterceptor();

    public void OnCompleted()
    {
    }

    public void OnError(Exception error)
    {
    }

    public void OnNext(DiagnosticListener listener)
    {
        if (listener.Name == DbLoggerCategory.Name)
        {
            listener.Subscribe(_noLockInterceptor);
        }
    }
}

Y registre esto como parte del inicio de la aplicación:

DiagnosticListener.AllListeners.Subscribe(new EfGlobalListener());

Viene para EntityFramework Core 3.0: https://github.com/aspnet/EntityFrameworkCore/issues/15066

Funcionará de la misma manera que el de EF 6

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *