Code First Entity Framework with MVC4 and Visual Studio 2012

From Logic Wiki
Jump to: navigation, search


Setting Up Database Step by Step

Click Here for PDF version

Step 1 – Create a new Project

First create the project in VS2012 by going to new project, giving it a name, selecting ASP.NET MVC4, selecting Internet Application, and ensuring Razor is selected. This will give you the base for a Code First EF MVC4 application. In fact, the Accounts Model is already set up with Entity Framework!

Step 2 – Define the Model

Next we create a very simple model that exemplifies how a 1 to many relationship using ICollection. The model is a little inconsistent to illustrate different techniques and annotation of the entity framework: custom db table names, custom KEY, and custom FK name; as well, it illustrates that traditional EF naming, which doesn’t require the annotation described.

[Table("dbUsers")] // Use this to use a different table name other than "Users"
   public class User
   {
       [Key]
       [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
       public int DbUserId { get; set; }
       public string Name { get; set; }

       public virtual ICollection Purchases { get; set; }
   }

   // This table will be called "Purchases" automatically
   public class Purchase
   {
       // Because standard naming is used, no need for [Key] ...
       public int PurchaseId { get; set; } 
       public int UserId { get; set; }
       public int ProductId { get; set; }

       [ForeignKey("UserId")] // Use this if the name of FK is different
       public virtual User User { get; set; }
       // No need to use ForeignKey because FK name is same as Key of Product
       public virtual Product Product { get; set; }

   }

   public class Product
   {
       public int ProductId { get; set; }
       public string Name { get; set; }
       public string Description { get; set; }

       public virtual ICollection Purchases { get; set; }
   }

Step 3 – Create the DbContext

In the same model file, I create a the DbContex object that tells EF which classes are going to be stored in the database. In this case, I name this “TestContext” as seen in code segment below. It may be useful to note that other options are available here such as turning off pluralization, pointing to a specific db connection, etc.

   public class TestContext : DbContext
   {
       public DbSet Users { get; set; }
       public DbSet Purchases { get; set; }
       public DbSet Products { get; set; }

   }

Step 4 – Add a Connection String

Next open up your “Web.config” and add a connection string in the <connectionStrings> node. If you followed the steps above, you should already have one named “DefaultConnection.” Whatever your choice of storage system, make sure you name your connection, “TestContext.” Entity framework will automatically associate this connection with the db context we created in step 3.

Step 5 – Add a Data Initializer

Entity Framework provides a very useful feature: the ability to initialize your tables with some sample data whenever the model changes. To do this create a new class that inherits from DropCreateDatabaseifModelChanges<DbContext>. Next we override the Seed(context) function where we add our products, purchases, and users. The method SaveChanges() in the DbContext object is run whenever you want to update the DB.

   public class TestInitializer : 
                   DropCreateDatabaseIfModelChanges 
   {
       protected override void Seed(TestContext context)
       {            
           var products = new List
           {
               new Product { Name = "Widget", 
                             Description = "A widget is a widget." },
               new Product { Name = "Crank", 
                             Description = "A crank for the  widget." }
           };
           products.ForEach(p => context.Products.Add(p));
           context.SaveChanges();

           var users = new List
           {
               new User { Name = "Joe" },
               new User { Name = "Lillith" }
           };
           users.ForEach(u => context.Users.Add(u));
           context.SaveChanges();

           var purchases = new List
           {
               new Purchase {  
                   Product = 
                       products.Where(p => p.Name == "Widget").First(),
                   User =
                       users.Where(u => u.Name == "Joe").First() }
           };
           purchases.ForEach(pr => context.Purchases.Add(pr));
           context.SaveChanges();
       }
   }

Step 6 – Set the Initializer in Global.asax.cs

Next we set the initializer in the Global.asax.cs file to ensure that it runs when it needs (when the model changes and the context is used).

public class MvcApplication : System.Web.HttpApplication
   {
       protected void Application_Start()
       {
           Database.SetInitializer(new TestInitializer());

...

Step 7 – Add the DbContext Object to a View in Order to Test

Usually I add the dbContext to the HomeController first (without even touching the Home View) in order to test out the implementation inside an ActionResult that I know I will run (visit with browser after running); I also add something to the data to ensure proper functionality and saving.

public class HomeController : Controller
   {
       private TestContext db = new TestContext();

       public ActionResult Index()
       {
           ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
           db.Products.Add(new Product { Name = "asdf" });
           db.SaveChanges();
           return View();
       }

  ...

The last step is to verify that the database, tables, and sample data were created properly in the DB. For this I usually run SQL Managment Studio and inspect the DB directly. If you did everything correctly, you should see a new database with the name that you’ve described in the connection string.