gpt4 book ai didi

entity-framework-core - 已创建超过 20 个 'IServiceProvider' 实例供 Entity Framework 内部使用

转载 作者:行者123 更新时间:2023-12-05 07:13:56 29 4
gpt4 key购买 nike

我在我的 ASP.NET Core 2.2 应用程序中收到此警告

warn: Microsoft.EntityFrameworkCore.Infrastructure[10402]More than twenty 'IServiceProvider' instances have been created for internal use by Entity Framework. This is commonly caused byinjection of a new singleton service instance into every DbContextinstance. For example, calling UseLoggerFactory passing in a newinstance each time--see https://go.microsoft.com/fwlink/?linkid=869049for more details. Consider reviewing calls on'DbContextOptionsBuilder' that may require new service providers to bebuilt.

花了一些时间后,我发现它发生在 startup.cs 中。我正在使用 IdentityServer3 + OpenIDCNnection 进行身份验证。

用户成功登录后,客户端应用程序授权用户确保用户存在于客户端应用程序的数据库中。

客户端应用的Startup.cs

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IAccountService, AccountService>();
services.AddDbContext<Data.Entities.MyDBContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
sqlServerOptions => sqlServerOptions.CommandTimeout(sqlCommandTimeout));
});

services.AddAuthentication(options =>
{
// removed for brevity purpose
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
// removed for brevity purpose
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{

options.Events = new OpenIdConnectEvents()
{
OnTokenValidated = async context =>
{
Data.Entities.UserAccount userAccount = null;
using (var serviceProvider = services.BuildServiceProvider())
{
using (var serviceScope = serviceProvider.CreateScope())
{
using (var accountService = serviceScope.ServiceProvider.GetService<IAccountService>())
{
userAccount = await accountService.Authorize(userName);
}
}
}

if (userAccount == null)
{
throw new UnauthorizedAccessException(string.Format("Could not find user for login '{0}' ", userName));
}
},
};
}
);
}
}

账户服务

public class AccountService : IAccountService
{
private bool _disposed = false;
private readonly MyDBContext_dbContext;

public AccountService(MyDBContext dbContext)
{
_dbContext = dbContext;
}

public UserAccount Authorize(string userName)
{
// Ensures user exists in the database
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;

if (disposing)
{
if (_dbContext != null)
{
_dbContext.Dispose();
}
// Free any other managed objects here.
}

// Free any unmanaged objects here.
_disposed = true;
}
}

AccountService.Authorize(userName) 将在每次成功登录时被调用。以此类推,第 21 位成功用户及以后我开始看到警告。

问题

1>在 OnTokenValidated 事件中,我正在创建服务提供者并立即处置它。为什么 EF 还在记录警告?
2>如何摆脱这个警告?

即使我使用范围创建 20 多个 DBContext,我也会收到此警告

NET Fiddle DEMO

最佳答案

(1) 您可以定义 AddDbContext 方法的 ServiceLifetime 参数,而不是处理 dbcontext。

contextLifetime: ServiceLifetime

The lifetime with which to register the DbContext service in the container.

optionsLifetime : ServiceLifetime

The lifetime with which to register the DbContextOptions service in the container.

EntityFrameworkServiceCollectionExtensions.AddDbContext Method

(2) 下面是logger和error trap的例子,可以用在启动类的configureservices方法上。

// define single service provider
using (var sp = new ServiceCollection()
.AddLogging(l => l.AddConsole())
.AddDbContext<MyDBContext>(options =>
{
options.UseSqlServer("Server=(local);Database=MyDB;Integrated Security=True",
sqlServerOptions => sqlServerOptions.CommandTimeout(120));
})
.BuildServiceProvider())

// define service logger
using (var logger = sp.GetService<ILoggerFactory>().CreateLogger<Program>())
{
try
{
for (int i = 1; i <= 25; i++)
{
using (var serviceScope = sp.CreateScope())
using (var accountService = sp.GetService<MyDBContext>())
{

}
}
}

// (2) catch the error warning
catch(ex: Exception)
{
logger.LogInformation($@"Error: {ex.ToString()}");
}
}

顺便说一句,EF 实体绝对是声明和运行时的静态类。因此,您必须在数据库架构更改时修改(或执行任何迁移步骤)类。

希望这对您有所帮助。

关于entity-framework-core - 已创建超过 20 个 'IServiceProvider' 实例供 Entity Framework 内部使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60047465/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com