gpt4 book ai didi

asp.net - 在 App_Start 中初始化和播种 Identity 的 DbContext

转载 作者:行者123 更新时间:2023-12-02 16:55:18 24 4
gpt4 key购买 nike

我使用的是最新的MVC、Identity、EntityFramework,以及官方的Identity sample solution .

App_Start() 中有很多运行数据库初始化程序的方法。 ,(例如(DropCreateDatabaseIfModelChangesDropCreateDatabaseAlways)。

我尝试过:

AppDbContext.Instance.Database.Initialize(true); // Instance is static builder 

问题是,使用 Identity/OWIN,播种函数将管理器对象从 OWIN 上下文中拉出(通过 HttpContext.Current.GetOwinContext() ),这显然在生命周期的早期并不存在。

var userManager = HttpContext.Current.GetOwinContext().GetUserManager<UserManager>();
var roleManager = HttpContext.Current.GetOwinContext().Get<RoleManager>();

所以我得到:

InvalidOperationException: No owin.Environment item was found in the context.

OWIN 上下文已正确设置,并且按预期运行。仅当我尝试在 App_Start 中访问它时才会出现这种情况我遇到了这个问题。

正在初始化 App_Start 中的数据库并不是绝对必要的,但我更喜欢显式代码,并且希望其中有各种初始化例程,包括数据库的创建/播种。我该怎么做?

最佳答案

@BrendanGreen 的评论给了我一个想法,这对我来说很有效。下面的所有内容只是我对 Identity 示例项目的编辑。

首先编辑DbContextInitializer:

public class DbContextInitializer : DropCreateDatabaseIfModelChanges<AppDbContext> {

protected override void Seed(AppDbContext context) {

// remove this, because the OWIN context does not yet exist:
//var userManager = HttpContext.Current.GetOwinContext().GetUserManager<AppUserManager>();
//var roleManager = HttpContext.Current.GetOwinContext().Get<AppRoleManager>();

// and replace it with:
var userManager = new AppUserManager<AppUser>(new UserStore<AppUser>(context));
var roleManager = new AppRoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

// ... etc. ...

base.Seed(context);
}

}

然后编辑AppDbContext:

public class AppDbContext : IdentityDbContext<AppUser> {

// no change: this static factory method is called in OWIN init
public static AppDbContext Create() { return new AppDbContext(); }

// no change: this static ctor called the first time this type is referenced
static AppDbContext() { Database.SetInitializer<AppDbContext>(new DbContextInitializer()); }

// changed: made ctor private
private AppDbContext() : base("name=DefaultConnection", false) { }

// add this: forces the initializer to run, even if it's already been run
public static void init() { Create().Database.Initialize(true); }

}

最后编辑Global.asax.cs:

protected void Application_Start() {
// ... etc.
DbContext.init(); // force initializer to run
// ... etc.
}

结果是数据库不再是延迟创建/延迟加载的,而是在 Application_Start 中初始化。有这个必要吗?不。但现在我所有的初始化代码都发生在一个地方,并且在调试时更容易跟踪事情。

关于asp.net - 在 App_Start 中初始化和播种 Identity 的 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25713425/

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