【问题标题】:Detect lazy-load in Entity Framework Core在 Entity Framework Core 中检测延迟加载
【发布时间】:2021-10-25 21:49:39
【问题描述】:

Entity Framework Core 3.1.2 - 我在DbContext 上启用了UseLazyLoadingProxies 以确保数据完整性,但如果使用它,我想在开发过程中抛出异常。

如何在每次 EF Core 延迟加载关系时执行一些代码?

【问题讨论】:

  • 您是否尝试过添加一个属性来告诉您该对象是否来自 Microsoft.EntityFrameworkCore.Infrastructure 中的“ILazyLoader”接口,如果是,那么很有可能它的加载被推迟了,仅此而已无论如何,我现在可以想到,如果有机会,我将在今天晚些时候进行更深入的了解。

标签: entity-framework-core lazy-loading


【解决方案1】:

我知道的唯一方法是诊断消息。在此处查看示例:https://www.domstamand.com/getting-feedback-from-entityframework-core-through-diagnostics

你想要的事件类是https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.diagnostics.lazyloadingeventdata

在应用程序的 DBContext 中

#if DEBUG
    static ApplicationDbContext()
    {
        // In DEBUG mode we throw an InvalidOperationException
        // when the app tries to lazy load data.
        // In production we just let it happen, for data
        // consistency reasons.
        DiagnosticListener.AllListeners.Subscribe(new DbContextDiagnosticObserver());
    }
#endif

然后是一个挂钩到 EF 通知的类

internal class DbContextDiagnosticObserver : IObserver<DiagnosticListener>
    {
        private readonly DbContextLazyLoadObserver LazyLoadObserver =
            new DbContextLazyLoadObserver();

        public void OnCompleted() { }

        public void OnError(Exception error) { }

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

最后是在发生延迟加载时抛出异常的类

internal class DbContextLazyLoadObserver : IObserver<KeyValuePair<string, object>>
    {
        public void OnCompleted() { }
        public void OnError(Exception error) { }

        public void OnNext(KeyValuePair<string, object> @event)
        {
            // If we see some Lazy Loading, it means the developer needs to
            // fix their code!
            if (@event.Key.Contains("LazyLoading"))
                throw new InvalidOperationException(@event.Value.ToString());
        }
    }

【讨论】:

    【解决方案2】:

    我用它来逐步摆脱我们代码库中的惰性代理使用:

    if (enableProxies)
    {
        builder.UseLazyLoadingProxies();
        var lazyLoadEvents = new[]
        {
            CoreEventId.NavigationLazyLoading,
            CoreEventId.DetachedLazyLoadingWarning,
            CoreEventId.LazyLoadOnDisposedContextWarning,
        };
    #if DEBUG
        builder.ConfigureWarnings(w => w.Throw(lazyLoadEvents));  //Lazyload now throws in DEBUG
    #else
        if (sp.GetService<IHostEnvironment>()?.IsEnvironment("PRD") ?? false)
        {   //logs LazyLoad events as error everywhere else
            builder.ConfigureWarnings(w => w.Log(lazyLoadEvents.Select(lle => (lle, LogLevel.Error)).ToArray())); 
        }
    #endif
    }
    

    这使得以下内容。在生产行为是不变的。在 DEBUG 中,使用延迟加载时会引发异常。在资格认证环境中,会记录一个错误。

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2018-06-21
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多