ASP.NET Core 2.0 MVC自定义数据库初始化程序类上的ObjectDisposedException

我在自定义数据库初始化程序类中遇到以下exception:

发生System.ObjectDisposedException HResult = 0x80131622
Message =无法访问已处置的对象。 此错误的常见原因是处理从依赖项注入解析的上下文,然后尝试在应用程序的其他位置使用相同的上下文实例。 如果您在上下文中调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。 如果使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例。 Source = StackTrace:Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()at Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext()at System.Runtime .ExceptionServices.ExceptionDispatchInfo.Throw()
位于System.Runtime.Exception服务9.d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
9.d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
9.d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()at Microsoft.AspNetCore.Identity.UserManager 1.d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()at Microsoft.AspNetCore.Identity.UserManager 1.d__78.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter )中的ExceptionServices.ExceptionDispatchInfo.Throw()在E:\中的LlabApp.Data.DbInitializer.d__4.MoveNext()中的GetGesult() C#projects \ Atenea \ LlabApp \ LlabApp \ LlabApp \ Data \ DbInitializer.cs:第58行

这是初始化器:

 public class DbInitializer : IDbInitializer { private readonly ApplicationDbContext _Context; private readonly UserManager _userManager; private readonly RoleManager _roleManager; public DbInitializer( ApplicationDbContext context, UserManager userManager, RoleManager roleManager) { _context = context; _userManager = userManager; _roleManager = roleManager; } public async void Initialize() { var adminUsers = _userManager.GetUsersInRoleAsync(RoleClaimValues.Admin).Result; if (adminUsers == null || adminUsers.Count == 0) { (...) } } } public interface IDbInitializer { void Initialize(); } 

这是startup.cs,我在ConfigureService添加了IDbInitializer的范围,然后从Configure调用它:

 public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationConnection"))); services.AddIdentity(o => { o.Password.RequireDigit = false; o.Password.RequiredLength = 4; o.Password.RequireLowercase = false; o.Password.RequireUppercase = false; o.Password.RequireNonAlphanumeric = false; o.User.RequireUniqueEmail = true; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddMvc(); // Add application services. services.AddTransient(); //Seed database services.AddScoped(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IDbInitializer dbInitializer) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); app.UseDatabaseErrorPage(); app.UseStatusCodePages("text/plain", "Status code page, status code: {0}"); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseAuthentication(); dbInitializer.Initialize(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } 

我不知道为什么exception会说问题可能是上下文被置于某个地方。

我还补充道

 .UseDefaultServiceProvider(options => options.ValidateScopes = false) 

.UseStartup() ,以防它是相对于作用域的东西,但exception是相同的。

我遇到了和你一样的问题。 您确实必须更改所有代码以返回Task 。 否则,在完成所有操作之前处理DbContext

数据库初始化在dotnet core 2.0中更改。 我创建了一个关于这个特定主题的博客。 有关详细信息,请参阅http://www.locktar.nl/programming/net-core/seed-database-users-roles-dotnet-core-2-0-ef/ 。

好的,问题在于这一行:

 public async void Initialize() 

因为它是一个异步方法,它等待内部,但因为它是无效的,ServiceProvider在到达第一个等待之后处理依赖,并在从启动返回方法调用并继续执行时离开上下文。

因此,解决方案是在DbInitializerIDbInitializer void更改为Task ,并在startap中转换dbInitializer参数并等待它完成:

 ((DbInitializer)dbInitializer).Initialize().Wait(); 

当然,调用异步方法然后等待所有这些方法完成并不是很有用,但我不知道是否可以将Configure方法设置为异步方法…所以这就是我找到的解决方案因为它只是用于在开发环境中播种数据库,所以我很满意。

任何进一步的建议将不胜感激。