我正在玩MVC 5,我创建了一个使用ASP.NET Identity的网站。我按照MSDN上这篇博客文章中的步骤,在Seed
方法中为我的数据库初始值设定项创建了一个用户和一个角色。
然而,我注意到该代码中使用的UserManager
和RoleManager
都实现了IDisposable,所以我稍微修改了代码,使其看起来像这样(因此,一旦我完成它们,就会处理它们):
protected override void Seed(ApplicationDbContext context)
{
using (var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)))
using (var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context)))
{
EnsureRoleCreated(roleManager, Roles.Administrator);
const string AdministratorUserName = "admin";
const string DefaultAdminPassword = "password";
var user = EnsureUserCreated(userManager, AdministratorUserName, DefaultAdminPassword);
EnsureUserIsInRole(userManager, user, Roles.Administrator);
}
base.Seed(context);
}
现在,当我的控制器操作试图访问DB时,我得到一个异常,说我的DbContext
已被释放。(我在控制器的构造函数中新建了一个DbContext
实例)。
[如果我删除了那些using()
语句,因此不处理UserManager
和RoleManager
,那么问题就消失了,所以肯定是那些using()
语句在起作用。]
这对我来说似乎很奇怪。如果处理这个问题的"正确"方法是不显式处理UserManager
和RoleManager
,那么当垃圾收集器启动时,它们最终肯定会被处理。由于这是不可预测的,随时都可能发生,这不意味着我的应用程序中有一个定时炸弹吗?
在我看来,既然我创建了DbContext
,我就应该负责处理它。为什么UserManager
和/或RoleManager
会处理他们没有创建的东西?
是RoleStore
处理DbContext
,即使它没有创建它。UserStore
具有一个DisposeContext
布尔属性,用于控制是否应释放上下文。如果使用将DbContext
作为输入的构造函数,则DisposeContext
为false。
这似乎已经在夜间构建中得到了修复。在这里,RoleStore还具有DisposeContext
属性,并且似乎可以按预期工作。