Hassaan
Hassaan

Reputation: 3991

Database.SetInitializer is not seeding the database?

I am using enitity framework version 6.1.0 code first approch. The database is just creating fine but when come to seeding part it is not seeding the override Seed Method.

How do i make to seed my data?

My testing implementation is as

public class Products
{
    public Products()
    {
        this.Categories = new HashSet<Categories>();
    }

    [ScaffoldColumn(false)]
    [Key()]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductId { get; set; }

    [Required,StringLength(100),Display(Name="Product Name")]
    public string Name { get; set; }

    public int? CategoryId { get; set; }
    public virtual ICollection<Categories>  Categories{ get; set; }
}

public class Categories
{
    [ScaffoldColumn(false)]
    [Key()]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryId { get; set; }

    [Required,StringLength(100),Display(Name="Category")]
    public string Name { get; set; }
    public virtual ICollection<Products> Products { get; set; }

}

The ProductsInitializer is inherited from DropIfModelchanges

 public class ProductsDatabaseInitializer : DropCreateDatabaseIfModelChanges<ETestContext>
 {
    protected override void Seed(ETestContext context)
    {
        GetCategories().ForEach(c => context.Categories.Add(c));
        GetProducts().ForEach(p => context.Products.Add(p));
        context.SaveChanges();

        base.Seed(context);
    }

    private static List<Categories> GetCategories()
    {
        var categories = new List<Categories>{
            new Categories{
                CategoryId=101,
                Name="Electronics"
            },
            new Categories{
                CategoryId=102,
                Name="Clothing"
            }
        };
        return categories;
    }

    private static List<Products> GetProducts()
    {
        var products = new List<Products>{
           new Products{
             CategoryId = 101,
             ProductId=1,
             Name="Laptops"
           },
           new Products{
             CategoryId = 101,
             ProductId=2,
             Name="Desktops"
           },
           new Products{
             CategoryId = 102,
             ProductId=3,
             Name="Male Clothing"
           },
           new Products{
             CategoryId = 102,
             ProductId=4,
             Name="Female Clothing"
           }
       };
        return products;
    }


}

And My DBcontext class is as

public class ETestContext : DbContext
{

    public ETestContext()
        : base("ETest")
    {

    }

    public DbSet<Categories> Categories { get; set; }
    public DbSet<Products> Products { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Categories>().HasMany<Products>(c => c.Products).WithMany(p => p.Categories)
            .Map(c =>
            {
                c.MapLeftKey("CategoryId");
                c.MapRightKey("ProductId");
                c.ToTable("CategoryProduct");
            });
        base.OnModelCreating(modelBuilder);
    }
}

In the global.asax I am implementing as

protected void Application_Start(object sender, EventArgs e)
{
   Database.SetInitializer(new Wb1.Model.ProductsDatabaseInitializer());
   using (var dbContext = new Wb1.Model.ETestContext())
   {
     if (!dbContext.Database.Exists())
     {
       dbContext.Database.Create();
     }
     dbContext.Database.Initialize(true);
   }
}

Upvotes: 0

Views: 289

Answers (1)

Yuliam Chandra
Yuliam Chandra

Reputation: 14640

You should call Initialize instead of Create, it has different implementation with the initializer.

Creates a new database on the database server for the model defined in the backing context. Note that calling this method before the database initialization strategy has run will disable executing that strategy. - MSDN

And since ProductsDatabaseInitializer is DropCreateDatabaseIfModelChanges, the moment you call Initialize, the database has been created so that the Seed method will not be executed, but if there is a model change, the Seed method will be executed because it's dropped and recreated.

The proper way should be just calling the Initialize without checking if it exists or not, because it's already derived from DropCreateDatabaseIfModelChanges, which means create if it doesn't exists and execute the Seed method, or drop and create if model's changed and execute the Seed method, otherwise do nothing.

Database.SetInitializer(new Wb1.Model.ProductsDatabaseInitializer());
using (var dbContext = new Wb1.Model.ETestContext())
{
    dbContext.Database.Initialize(true);
}

Upvotes: 1

Related Questions