检测Entity Framework Core中的惰性加载

6

实体框架核心3.1.2 - 我已经在我的DbContext上启用了UseLazyLoadingProxies以确保数据完整性,但我希望在开发过程中如果使用它会抛出异常。

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


1
你尝试过添加一个属性来告诉你对象是否从Microsoft.EntityFrameworkCore.Infrastructure中的“ILazyLoader”接口派生吗?如果是,那么它很可能是延迟加载的。这是我现在能想到的全部了。如果我有机会,今天稍后我会更深入地研究一下。 - shawty
2个回答

7

我使用这个方法逐步消除了我们代码库中懒惰的代理使用:

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模式下,使用lazy-load时会引发异常。在测试环境中,会记录一个错误。

7
我所知道的唯一方法是使用诊断消息。可查看此处的示例:https://www.domstamand.com/getting-feedback-from-entityframework-core-through-diagnostics。 您需要的事件类为https://learn.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());
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,