Can I configure an interceptor in EntityFramework Core?

后端 未结 3 1291
时光说笑
时光说笑 2020-12-03 01:34

In the old (pre .net core) era\'s entity framework 6 as shown in this blog post there is a way to configure an interceptor which can log all slow queries including a stack b

相关标签:
3条回答
  • 2020-12-03 02:01

    It is coming for EntityFramework Core 3.0: https://github.com/aspnet/EntityFrameworkCore/issues/15066

    It will work the same way as the one in EF 6

    0 讨论(0)
  • 2020-12-03 02:18

    Update: Interception of database operations is now available in EF Core 3.0.

    Original answer:


    EF Core does not have "interceptors" or similar lifecycle hooks yet. This feature is tracked here: https://github.com/aspnet/EntityFramework/issues/626.

    Overriding a low-level component may be unnecessary if all you want is log output. Many low-level EF Core components already produce logging, logging including query execution. You can configure EF to use a custom logger factory by calling DbContextOptionsBuilder.UseLoggerFactory(ILoggerFactory factory). (See https://docs.asp.net/en/latest/fundamentals/logging.html and https://github.com/aspnet/Logging for more details on this logger interface.) EF Core produces some notable log events with well-define event IDs. (See Microsoft.EntityFrameworkCore.Infrastructure.CoreLoggingEventId in 1.0.0-rc2, which was renamed to justMicrosoft.EntityFrameworkCore.Infrastructure.CoreEventId for 1.0.0 RTM.) See https://docs.efproject.net/en/latest/miscellaneous/logging.html for examples of doing this.

    If you need additional logging beyond what EF Core components already produce, you will need to override EF Core's lower-level components. This is best done by overriding the existing component and added this overridding version to EF via dependency injection. Doing this requires configuring a custom service provider for EF to use internally. This is configured by DbContextOptionsBuilder.UseInternalServiceProvider(IServiceProvider services) See https://docs.efproject.net/en/latest/miscellaneous/internals/services.html for more details on how EF uses services internally.

    0 讨论(0)
  • 2020-12-03 02:19

    Here is an example found on github from ajcvickers on how to use an Interceptor in EF CORE (2.2 at the time of answering this question):

    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
            }
        }
    }
    

    Next, create a global listener for EF diagnostics. Something like:

    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);
            }
        }
    }
    

    And register this as part of application startup:

    DiagnosticListener.AllListeners.Subscribe(new EfGlobalListener());
    
    0 讨论(0)
提交回复
热议问题