加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

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

发布时间:2020-12-16 03:35:13 所属栏目:asp.Net 来源:网络整理
导读:我正在使用最新的MVC,Identity,EntityFramework以及官方 Identity sample solution. 有很多方法可以在App_Start()中运行数据库初始化程序(例如(DropCreateDatabaseIfModelChanges,DropCreateDatabaseAlways)). 我试过了: AppDbContext.Instance.Database.In
我正在使用最新的MVC,Identity,EntityFramework以及官方 Identity sample solution.

有很多方法可以在App_Start()中运行数据库初始化程序(例如(DropCreateDatabaseIfModelChanges,DropCreateDatabaseAlways)).

我试过了:

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:在上下文中找不到owin.Environment项.

OWIN上下文已正确设置,并按预期运行.只有当我尝试在App_Start中访问它时才会遇到此问题.

在App_Start中初始化db并不是绝对必要的,但我更喜欢显式代码,并且需要各种初始化例程,包括db的创建/接种.我怎么做?

解决方法

@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.
  }

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读