我正在构建一个 ASP.NET Core 6.0 Web 应用程序,我创建了一个使用 Microsoft Identity 的网站,该网站创建了 ApplicationDbContext.cs
文件:
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Settingw> Settings { get; set; }
}
接下来我创建了一个Settings
存储库和存储库界面。运行所有内容,进行测试,一切正常。
现在我尝试从该存储库内部调用 dbcontext,但收到错误
Cannot consume scoped service applicationdbcontext from singleton
我被困住了,不知道我做错了什么。
这是我的program.cs
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddSingleton<ISettingsRepository, SettingsRepository>(); //errors here
var app = builder.Build();
SettingsRepository.cs
:
public class SettingsRepository : ISettingsRepository
{
private readonly ApplicationDbContext _dbContext;
public SettingsRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public Settings Settings()
{
return _dbContext.Settings.AsNoTracking().First();
}
}
最佳答案
就像 Steve Py 在评论中提到的那样,您需要更改设置存储库服务的生命周期,如下所示:
builder.Services.AddScoped<ISettingsRepository, SettingsRepository>();
默认情况下,EF 上下文具有作用域生命周期。
- 单例:服务创建一次,并且为下一个请求返回相同的实例
- 范围:每个“范围”创建一次,并且由于 ASP.NET Core 为请求创建一个范围,这实际上意味着在典型场景中每个请求创建一次服务
- transient :每次需要服务时创建
您不应依赖生命周期较短的服务。 在这种情况下,您的存储库(单例)取决于上下文(作用域)。 问题是您的存储库仅创建一次,但它所依赖的上下文是每个范围的服务,并且会在请求完成时被处置。 在这种情况下,降低存储库的生命周期是正确的选择。
关于asp.net-core - 无法使用单例中的作用域服务 applicationdbcontext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76863469/