TapiocaCom
TapiocaCom

Reputation: 363

Database Initializer not being called in EF 5 + MVC 3

I know this question might be duplicated, but I haven't found any solution for my problem yet.

I have:

protected void Application_Start()
        {
            Database.SetInitializer(new DatabaseSeeder());
            DatabaseContext c = new DatabaseContext();
            c.Database.Initialize(true);

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);


        }

my database seeder is:

public class DatabaseSeeder : DropCreateDatabaseAlways<DatabaseContextBase>
    {
        protected override void Seed(DatabaseContextBase context)
        {
            base.Seed(context);

            var roles = new[] {"Admin", "User"};
            foreach (var role in roles)
            {
                context.Roles.Add(new UserRole {FullName = role});
            }

            context.SaveChanges();
        }
    }

and my context is:

public abstract class DatabaseContextBase : DbContext
    {
        public DbSet<UserRole> Roles { get; set; }
        public DbSet<UserAndPermissionInGroup> UserAndPermissions { get; set; }
        public DbSet<GeneralUser> Users { get; set; }
        public DbSet<Group> Groups { get; set; }
        public DbSet<Forum> Forums { get; set; } 

        public DatabaseContextBase() :base("ForumDb")
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Comment>()
                .HasRequired(e => e.Owner)
                .WithMany(t => t.Comments)
                .HasForeignKey(e => e.OwnerId)
                .WillCascadeOnDelete(false);
        }
    }

And finally:

public class DatabaseContext : DatabaseContextBase

{

}

The problem is that, even with this initializer, I get the following error:

The model backing the 'DatabaseContext' context has changed since the database was created. Consider using Code First Migrations to update the database

I am using EF 5 code first in an ASP.NET MVC 3 project. Any suggestions?

Upvotes: 1

Views: 7647

Answers (4)

Merwer
Merwer

Reputation: 546

I'm not sure if this would work, but could you do something like this?

DatabaseSeeder<TContextType> : DropCreateDatabaseAlways<TContextType> where TContextType : DatabaseContextBase

Upvotes: 0

TapiocaCom
TapiocaCom

Reputation: 363

It looks like Database.SetInitializer does not work for derived types. I changed the initializer from

public class DatabaseSeeder : DropCreateDatabaseAlways<DatabaseContextBase>

to

public class DatabaseSeeder : DropCreateDatabaseAlways<DatabaseContext>

and now the code:

Database.SetInitializer(new DatabaseSeeder());
DatabaseContext c = new DatabaseContext();
c.Database.Initialize(true);

works pretty well. Thanks for all answers.

Upvotes: 4

Grixxly
Grixxly

Reputation: 464

Something like the following?

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions
            .Remove<System.Data.Entity.Database.IncludeMetadataConvention>()
            .Entity<Comment>()
            .HasRequired(e => e.Owner)
            .WithMany(t => t.Comments)
            .HasForeignKey(e => e.OwnerId)
            .WillCascadeOnDelete(false);
    }

Upvotes: 0

emre nevayeshirazi
emre nevayeshirazi

Reputation: 19241

If you are good with losing your data, when you make changes to your models, try following.

DatabaseSeeder : DropCreateDatabaseIfModelChanges<DatabaseContextBase>

Instead of

DatabaseSeeder : DropCreateDatabaseAlways<DatabaseContextBase>

That way, when you make changes to your model, your database will be recreated using your up to date models and seed method will be called.

If you want to preserve your data, you should start reading about migrations.

  1. Code-First Migrations
  2. Automatic Migrations

Upvotes: 2

Related Questions