Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seeding not working in Entity Framework Code First Approach

I am developing a .Net project. I am using entity framework code first approach to interact with database. I am seeding some mock data to my database during development. But seeding is not working. I followed this link - http://www.entityframeworktutorial.net/code-first/seed-database-in-code-first.aspx.

This is my ContextInitializer class

public class ContextInitializer : System.Data.Entity.CreateDatabaseIfNotExists<StoreContext>
    {

        protected override void Seed(StoreContext context)
        {
            IList<Brand> brands = new List<Brand>();
            brands.Add(new Brand { Name = "Giordano" ,TotalSale = 1 });
            brands.Add(new Brand { Name = "Nike" , TotalSale = 3 });

            foreach(Brand brand in brands)
            {
                context.Brands.Add(brand);
            }
            base.Seed(context);
            context.SaveChanges();

        }
    }

This is my context class

public class StoreContext : DbContext,IDisposable
    {
        public StoreContext():base("DefaultConnection")
        {
            Database.SetInitializer(new ContextInitializer());
        }

        public virtual DbSet<Category> Categories { get; set; }
        public virtual DbSet<Brand> Brands { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
   }

This is my brand class

public class Brand
    {
        public int Id { get; set; }
        [Required]
        [MaxLength(40)]
        public string Name { get; set; }
        public int TotalSale { get; set; }
    }

I searched solutions online and I followed instructions. I run context.SaveChanges as well. But it is not seeding data to database. Why it is not working?

like image 850
Wai Yan Hein Avatar asked Oct 19 '25 16:10

Wai Yan Hein


2 Answers

You are taking the wrong initializer, CreateDatabaseIfNotExists is called only if the database not exists!

You can use for example DropCreateDatabaseIfModelChanges:

Solution 1)

public class ContextInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<StoreContext>
{

You have to take care with this approach, it !!!removes!!! all existing data.

Solution 2)

Create a custom DbMigrationsConfiguration:

public class Configuration : DbMigrationsConfiguration<StoreContext>
{
    public Configuration()
    {
        // Take here! read about this property!
        this.AutomaticMigrationDataLossAllowed = true;
        this.AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(StoreContext context)
    {
        IList<Brand> brands = new List<Brand>();
        brands.Add(new Brand { Name = "Giordano", TotalSale = 1 });
        brands.Add(new Brand { Name = "Nike", TotalSale = 3 });

        foreach (Brand brand in brands)
        {
            context.Brands.AddOrUpdate(m => m.Name, brand);
        }
        base.Seed(context);
        context.SaveChanges();
    }
}

In this way you can called( !!Before you create the DbContext or in the DbContext constructor!!):

// You can put me also in DbContext constuctor     
Database.SetInitializer(new MigrateDatabaseToLatestVersion<StoreContext , Yournamespace.Migrations.Configuration>("DefaultConnection"));

Notes:

  • DbMigrationsConfiguration need to know about the connection string you can provide this info in the constructor or from outside.
  • In Your DbMigrationsConfiguration you can configure also:
    • MigrationsNamespace
    • MigrationsAssembly
    • MigrationsDirectory
    • TargetDatabase

If you leave everything default as in my example then you do not have to change anything!

like image 75
Bassam Alugili Avatar answered Oct 22 '25 04:10

Bassam Alugili


Setting the Initializer for a Database has to happen BEFORE the context is ever created so...

    public StoreContext():base("DefaultConnection")
    {
        Database.SetInitializer(new ContextInitializer());
    }

is much to late. If you made it static, then it could work:

    static StoreContext()
    {
        Database.SetInitializer(new ContextInitializer());
    }
like image 22
Erik Philips Avatar answered Oct 22 '25 06:10

Erik Philips