Reputation: 14771
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?
Upvotes: 4
Views: 4108
Reputation: 16983
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:
If you leave everything default as in my example then you do not have to change anything!
Upvotes: 4
Reputation: 1228
Your code is working if you delete your existing database and the EF will create and seeding the data
Or
You can use DbMigrationsConfiguration
insted of CreateDatabaseIfNotExists
and change your code as follow:
First you have to delete the existing database
ContextInitializer class
public class ContextInitializer : System.Data.Entity.Migrations.DbMigrationsConfiguration<StoreContext>
{
public ContextInitializer()
{
this.AutomaticMigrationDataLossAllowed = true;
this.AutomaticMigrationsEnabled = true;
}
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();
}
}
StoreContext
public class StoreContext : DbContext, IDisposable
{
public StoreContext() : base("DefaultConnection")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<StoreContext, ContextInitializer>());
// Database.SetInitializer(new ContextInitializer());
}
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Brand> Brands { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
Then any change in your seed will automatically reflected to your database
Upvotes: 0
Reputation: 54618
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());
}
Upvotes: 1