Hi.

I'm working on this project where I'm supposed to make a simple online store using ASP.net, MVC4 and Entity Framework.

I'm on this part where I want to add some products to a database everytime I run my project, and these products are the one I'm going to list on my Homepage (you can buy these products). The problem is that I'm not sure how to add these products to the database everytime I run the project and only then. Earlier before I had experience on loading the data into the database with Page_Load, but since I'm not using Webforms, I cant do it this way.

Is there any ways I can load my product data into database, so I acually can list my products on my website? I want to add the products to the database everytime I start the project, and only then. Want them to stay there as well, do the project wont use so long time to start up everytime.

Thanks in advance.

Here's some of my code:

public class Product
    {
        [Key]
        public int ID { get; set; }
        public string ProductName { get; set; }
        public double Pris { get; set; }
        public string Description { get; set; }
        public string GenreName { get; set; }

        public virtual Genre Genre { get; set; }
    }

    public class Genre
    {
        [Key]
        public string GenreName { get; set; }
        public List<Product> Products { get; set; }
    }

    public class ContextClass : DbContext
    {
        public ContextClass()
            : base("name=Product")
        {
            Database.CreateIfNotExists();
        }

        public DbSet<Product> Products { get; set; }
        public DbSet<KGenre> Genres { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Genre>().HasKey(k => k.GenreName);
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }

    // These are the data I want to add now. How should I do this? What method should I use? Where should I place it?
            var gen = new List<Genre>
            {
                new Genre { GenreName = "Computer" },
                new Genre { GenreName = "Cellphones" },
                new Genre { GenreName = "Games" }
            };

            new List<Product>
            {
                new Produkt { ProductName = "Samsung Galaxy S4", Genre = Genres.Single(k => k.GenreName == "Cellphones"), Pris = 4000.00, Description = "Brand new S4", genreName = "Cellphones" },
                new Produkt { ProductName = "LG G2", Genre = Genres.Single(k => k.GenreName == "Cellphones"), Pris = 4500.00, Description = "This is LGG2", genreName = "Cellphones" },
                new Produkt { ProductName = "Ipad Mini", Genre = Genres.Single(k => k.GenreName == "Computer"), Pris = 2559.00, Description = "Ipad mini here", genreName = "Computer" },
                new Produkt { ProductName = "Nexus 7 (2013)", Genre = Genres.Single(k => k.GenreName == "Computer"), Pris = 2222.00, Description = "This is nexus", genreName = "Computer" },
                new Produkt { ProductName = "GTA 5", Genre = Genres.Single(k => k.GenreName == "Games"), Pris = 199.00, Description = "This is GTA", genreName = "Games" },
                new Produkt { ProductName = "Fifa 15", Genre = Genres.Single(k => k.GenreName == "Games"), Pris = 40.00, Description = "This is fifa", genreName = "Games" }
            }
        }
    }

You need to create your own custom initialiser, override the Seed method and set this initialiser for your Context.

Example;

public class DbInitialiser : CreateDatabaseIfNotExists<ContextClass>
{
    protected override void Seed(ContextClass context)
    {
        context.Genre.Add(new Genre { GenreName = "Computer" });
        // Add everything as necessary
    }
}

This needs to be set once and only once when your application runs. So, I would place it in the static constructor of your context as you can guarantee that it gets run only once and only when necessary.

public class ContextClass : DbContext
{
    static ContextClass()
    {
        Database.SetInitializer<ContextClass>(new DbInitialiser());
    }

    /* rest of code here */
}

Edited 3 Years Ago by Ketsuekiame

Hello, and thanks for the answer. I managed to fix it at last, but everytime I change some of the variables on Product or Genre class (like add a new ID, or change variabel name), I have to delete the database manually from the folder which is a bit annoying. I get this ASP.NET MVC4 Code First - 'Cannot attach the file as database' exception error. Not a big deal though.

However, there's one more problem I encountered. Adding the genres to DB is fine, but adding the products is weird. Under the coloumn "ProductName" in my database, I get the GenreName (instead of Nexus 7 (2013), it's Computer).
Anything wrong with my add method?

public class DbInitialiser : CreateDatabaseIfNotExists<ContextClass>
    {
        protected override void Seed(ContextClass context)
        {
            var gen = new List<Genre>
            {
                new Genre { GenreName = "Computer" },
                new Genre { GenreName = "Cellphones" },
                new Genre { GenreName = "Games" }
            };

            new List<Product>
            {
                new Product { ProductName = "Samsung Galaxy S4", Genre = Genres.Single(k => k.GenreName == "Cellphones"), Pris = 4000.00, Description = "Brand new S4" },
                new Product { ProductName = "LG G2", Genre = Genres.Single(k => k.GenreName == "Cellphones"), Pris = 4500.00, Description = "This is LGG2" },
                new Product { ProductName = "Ipad Mini", Genre = Genres.Single(k => k.GenreName == "Computer"), Pris = 2559.00, Description = "Ipad mini here" },
                new Product { ProductName = "Nexus 7 (2013)", Genre = Genres.Single(k => k.GenreName == "Computer"), Pris = 2222.00, Description = "This is nexus" },
                new Product { ProductName = "GTA 5", Genre = Genres.Single(k => k.GenreName == "Games"), Pris = 199.00, Description = "This is GTA"},
                new Product { ProductName = "Fifa 15", Genre = Genres.Single(k => k.GenreName == "Games"), Pris = 40.00, Description = "This is fifa" }
            }.ForEach(a => context.Products.Add(a));
        }
    }

I removed the variable genreName from Product class.

There is another base initialisation class which will drop and recreate the the database if you change your model: DropCreateDatabaseIfModelChanges<TContext> if you create another initialiser, or, change the class on the current one to that, then you will get the functionality you require.

As for why you're getting the wrong data in the field, I don't know. I do notice however, that you're not adding your data to the context and so not sure how you're getting it to your database there at all...

Hello.

If you look at line 20, I'm using a ForEach loop to add the data to the table. The problem is that the ProductName gives me GenreName..

Is it possible to use both DropCreateDatabaseIfModelChanges and CreateDatabaseIfNotExists?

This article has been dead for over six months. Start a new discussion instead.