我在自定义数据库初始化程序类中遇到以下异常:
发生System.ObjectDisposedException HResult = 0x80131622
Message =无法访问已处置的对象。导致此错误的常见原因 正在处理从依赖注入解决的上下文 然后尝试在你的其他地方使用相同的上下文实例 应用。如果您正在调用Dispose(),则可能会发生这种情况 上下文,或将上下文包装在using语句中。如果你是 使用依赖注入,你应该让依赖注入 容器负责处理上下文实例。 Source = StackTrace:at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() 在Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() 在 Microsoft.EntityFrameworkCore.DbContext.d__48.MoveNext() 在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore9.<CreateAsync>d__22.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
1.GetResult() 在 Microsoft.AspNetCore.Identity.UserManager
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.<CreateAsync>d__73.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
1.GetResult() 在 Microsoft.AspNetCore.Identity.UserManager
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.<CreateAsync>d__78.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() 在E:\ C#中的LlabApp.Data.DbInitializer.d__4.MoveNext() projects \ Atenea \ LlabApp \ LlabApp \ LlabApp \ Data \ DbInitializer.cs:第58行
这是初始化程序:
public class DbInitializer : IDbInitializer
{
private readonly ApplicationDbContext _Context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
public DbInitializer(
ApplicationDbContext context,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> 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,我在IDbInitializer
中添加了ConfigureService
的范围,然后从Configure
调用它:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ApplicationConnection")));
services.AddIdentity<ApplicationUser, ApplicationRole>(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<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, MessageServices>();
//Seed database
services.AddScoped<IDbInitializer, DbInitializer>();
}
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?}");
});
}
}
我不知道为什么异常会说问题可能是上下文被放置在某个地方。
我还添加了
.UseDefaultServiceProvider(options =>
options.ValidateScopes = false)
在.UseStartup<Startup>()
之后,以防它是相对于范围的东西,但异常是相同的。
答案 0 :(得分:2)
我遇到了和你一样的问题。
您确实必须更改所有代码才能返回Task
。否则,DbContext
将在所有操作完成之前处理。
在dotnet core 2.0中更改了数据库初始化。我创建了一个关于这个特定主题的博客。 有关详细信息,请参阅http://www.locktar.nl/programming/net-core/seed-database-users-roles-dotnet-core-2-0-ef/。
答案 1 :(得分:0)
好的,问题在于这一行:
public async void Initialize()
因为它是一个异步方法,它在内部等待,但因为它是无效的,所以ServiceProvider在到达第一个await之后处理dependecies,并在从启动时返回方法调用并继续执行时离开上下文。
因此,解决方案是在void
和Task
将DbInitializer
更改为IDbInitializer
,并在startap中转换dbInitializer参数并等待它完成:
((DbInitializer)dbInitializer).Initialize().Wait();
当然调用异步方法然后等待所有这些方法完成并不是很有用,但我不知道是否可以将Configure方法设置为异步方法...这就是解决方案我发现,因为它只是为了在开发环境中播种数据库,我很高兴。
任何进一步的建议将不胜感激。