2014-09-07 19 views
5

En son MVC, Identity, EntityFramework ve resmi Identity sample solution kullanıyorum. . App_Start() bir veritabanı başlatıcı çalıştırmak için birçok yol vardırApp_Start uygulamasında Identity'nin DbContext'i başlatılıyor ve ekleniyor

, (örneğin (DropCreateDatabaseIfModelChanges, DropCreateDatabaseAlways)

Denedim:

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

Sorun olduğunu Kimlik/Owin, ekmeyle işlev, yönetici nesnelerini OWIN bağlamından (HttpContext.Current.GetOwinContext() aracılığıyla) çeker, ki bu da, yaşam döngüsünün başlarında bu var olmadığı anlamına gelir.

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

Yani olsun:

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

Owin bağlam düzgün kurulum ve beklendiği gibi çalışır. Sadece bu sorunu alıyorum App_Start içinde erişmeye çalışırsam.

db'nin App_Start sürümünde başlatılması kesinlikle gerekli değildir, ancak açık kodları tercih ediyorum ve db'nin oluşturulması/eklenmesi dahil olmak üzere orada çeşitli giriş yordamları istiyorum. Bunu nasıl yaparım?

+1

Bunun yerine bir "UserManager" ve/veya "RoleManager" örneği oluşturamıyor musunuz? –

+0

@BrendanGreen, OWIN'den geçmeden bunu yapamayacağımı bilmiyordu. Benim için çalışan bir cevap eklendi. –

cevap

9

@ BrendanGreen'in yorumu bana bir fikir verdi. Aşağıdaki tüm şeyler sadece Identity örnek projesine yaptığım düzenlemeler.

İlk düzenleme 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); 
    } 

} 

Sonra AppDbContext düzenleyin:

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); } 

} 

Ve nihayet düzenlemek Global.asax.cs:

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

sonuç db artık olmasıdır tembel oluşturulmuş/tembel yüklü, ancak başlatılmış Application_Start. Bu gerekli mi? Hayır. Fakat şimdi tüm init kodum tek bir yerde gerçekleşiyor ve hata ayıklama sırasında bir şeyleri takip etmek daha kolay.

+0

Kendi sorununuzu sıralamak için kudretler – trailmax

+2

OWIN son çözümde bütün bunları nasıl ortaya koyuyor? – Luke