在 Entity Framework 核心中检测延迟加载
Detect lazy-load in Entity Framework Core
Entity Framework Core 3.1.2 - 我在 DbContext
上启用了 UseLazyLoadingProxies
以确保数据完整性,但如果使用它,我想在开发过程中抛出异常。
每次 EF Core 延迟加载关系时如何执行一些代码?
我知道的唯一方法是诊断消息。请在此处查看示例:https://www.domstamand.com/getting-feedback-from-entityframework-core-through-diagnostics.
您想要的活动 class 是 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
然后 class 挂接到 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);
}
}
最后 class 每当发生延迟加载时都会抛出异常
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());
}
}
我用它来逐步摆脱代码库中的惰性代理使用:
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 中,使用延迟加载时会引发异常。在鉴定环境中,记录错误。
Entity Framework Core 3.1.2 - 我在 DbContext
上启用了 UseLazyLoadingProxies
以确保数据完整性,但如果使用它,我想在开发过程中抛出异常。
每次 EF Core 延迟加载关系时如何执行一些代码?
我知道的唯一方法是诊断消息。请在此处查看示例:https://www.domstamand.com/getting-feedback-from-entityframework-core-through-diagnostics.
您想要的活动 class 是 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
然后 class 挂接到 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);
}
}
最后 class 每当发生延迟加载时都会抛出异常
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());
}
}
我用它来逐步摆脱代码库中的惰性代理使用:
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 中,使用延迟加载时会引发异常。在鉴定环境中,记录错误。