【问题标题】:The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations自创建数据库以来,支持“ApplicationDbContext”上下文的模型已更改。考虑使用 Code First 迁移
【发布时间】:2015-02-13 22:11:39
【问题描述】:

我自定义了Microsoft.AspNet.Identity 类。代码如下:

public class ApplicationUserRole : IdentityUserRole<Guid>
{
}

public class ApplicationUserClaim : IdentityUserClaim<Guid>
{
}

public class ApplicationUserLogin : IdentityUserLogin<Guid>
{

}

public class ApplicationRole : IdentityRole<Guid, ApplicationUserRole>
{
    public ApplicationRole() { }
    public ApplicationRole(string name) { Name = name; }
}

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, Guid, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationUserStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

public class ApplicationRoleStore : RoleStore<ApplicationRole, Guid, ApplicationUserRole>
{
    public ApplicationRoleStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

public class ApplicationUser : IdentityUser<Guid, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUser>().HasKey(l => l.Id).ToTable("tbl_Users", "membership");
        modelBuilder.Entity<ApplicationRole>().HasKey(l => l.Id).ToTable("tbl_Roles", "membership");
        modelBuilder.Entity<ApplicationUserClaim>().HasKey(l => l.Id).ToTable("tbl_UserClaims", "membership");
        modelBuilder.Entity<ApplicationUserLogin>().HasKey(l => new { l.UserId, l.ProviderKey, l.LoginProvider }).ToTable("tbl_UserLogins", "membership");
        modelBuilder.Entity<ApplicationUserRole>().HasKey(l => new { l.RoleId, l.UserId }).ToTable("tbl_UserRoles", "membership");
    }

当我第一次运行它时,一切正常,在 SQL Server 中创建表;但是如果我在类ApplicationUser 中添加属性(例如public string FirstName {get; set;})并运行它以在数据库中进行更改,则会引发错误:

支持“ApplicationDbContext”上下文的模型在创建数据库后发生了变化。考虑使用 Code First 迁移来更新数据库

我知道我必须启用迁移,但是有什么方法可以在没有迁移的情况下做到这一点,因为它会创建自己的文件夹(配置)并在其中生成类?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework asp.net-mvc-5 code-first


    【解决方案1】:

    只需在 Global.asax 注册此条目:

    protected void Application_Start()
    {
      //Other calls...
      Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ApplicationDbContext>());
    }
    

    这将在每次其模型更改时重新创建您的身份数据库。 Identity 的 Context 使用与您使用 EF 创建的任何数据库相同的概念。

    您可以使用其他方法,请查看此处了解更多信息和示例:System.Data.Entity Namespace

    编辑:

    要每次都为您的数据库播种它的滴,您应该像这样实现Initializer Class,并覆盖Seed 方法以放置一些“假”数据:

    public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
    {
        protected override void Seed(ApplicationDbContext context)
        {
            var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
            var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
    
            if (!RoleManager.RoleExists("admim"))
            {
                var roleresult = RoleManager.Create(new IdentityRole(Administrador));
            }
    
            //Create User=Admin with password=123456
            var user = new ApplicationUser();
            user.UserName = "sysadmin";
            var adminresult = UserManager.Create(user, "123456");
    
            //Add User Admin to Role Admin
            if (adminresult.Succeeded)
            {
                var result = UserManager.AddToRole(user.Id, "admin");
            }
        }
     }
    

    然后在 Global.asax 中注册这个:

    protected void Application_Start()
    {
      //Other calls...
      Database.SetInitializer(new ApplicationDbInitializer());
    } 
    

    【讨论】:

    • 我做到了,但现在抛出了这个错误。无法删除数据库“TestSecurity”,因为它当前正在使用中。
    • @www1986 您可能正在从 Management Studio 或 Visual Studio Server Explorer 访问此数据库。确保没有打开到此数据库的连接,否则将无法删除它正在使用的东西。关闭您用于查询此数据库的任何应用程序。如果不起作用,只需暂停并重新启动 SQL Server 实例,这将关闭任何剩余的连接。
    • 你怎么可能建议DropCreateDatabaseIfModelChanges 来解决这个问题?您是否意识到有人阅读您的答案并将其放入生产代码中会有很大的变化?
    • @Mihai-AndreiDinculescu 我的答案适合这个问题,请在执行此操作之前阅读所有内容:“[但是有没有办法在没有迁移的情况下做到这一点]”
    • @Fals 是的,它有效。但是现在我遇到了另一个问题,正如您在 Database.SetInitializer(new DropCreateDatabaseIfModelChanges()) 上面写的那样,这会删除数据库,然后创建并且所有旧信息都丢失了。如何在不丢失旧记录的情况下做到这一点?
    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多