pan*_*nis 4 .net c# entity-framework-core
我在 EF Core 7 中使用 .NET 7 有以下代码:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.AddInterceptors(new IgnoreTrackingInterceptor());
}
public class IgnoreTrackingInterceptor : IMaterializationInterceptor
{
public object InitializedInstance(MaterializationInterceptionData materializationData, object instance)
{
if (instance is ISomeEntity someEntity)
materializationData.Context.Entry(someEntity).State = EntityState.Detached;
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
使用该应用程序一段时间后,它会抛出ManyServiceProvidersCreatedWarning异常。
An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.ManyServiceProvidersCreatedWarning': More than twenty 'IServiceProvider' instances have been created for internal use by Entity Framework. This is commonly caused by injection of a new singleton service instance into every DbContext instance
Run Code Online (Sandbox Code Playgroud)
当我评论时,该optionsBuilder.AddInterceptors(new IgnoreTrackingInterceptor());应用程序可以正常运行几个小时。
我在这里做错了什么?
问题是IMaterializationInterceptor是 EF Core ISingletonInterceptor接口之一,它
所有注册为单例服务的实体框架拦截器的基本接口。这意味着单个实例被多个
DbContext实例使用。实现必须是线程安全的。
即使该接口不添加成员,EF Core 基础结构也会将其用作标记,并且确实期望实现在 DI 中注册为单例或静态实例,因为这些是 EF Core 服务提供者缓存密钥哈希代码的一部分,并且相等(通过引用进行比较)。
所以修改代码如下:
public class IgnoreTrackingInterceptor : IMaterializationInterceptor
{
public static IgnoreTrackingInterceptor Instance { get; } = new();
private IgnoreTrackingInterceptor() { }
// the rest as is
}
Run Code Online (Sandbox Code Playgroud)
和
optionsBuilder.AddInterceptors(IgnoreTrackingInterceptor.Instance);
Run Code Online (Sandbox Code Playgroud)
问题应该得到解决。
| 归档时间: |
|
| 查看次数: |
1765 次 |
| 最近记录: |