If you haven’t already, go install mvc 3 RC. This will also install NuGet which we will be using. You can read more about mvc 3 and NuGet on ScottGu’s blog.
Create a new MVC 3 Web Application and use Razor for the view engine. Probably a good idea to tick on the unit test box to create unit tests.

Next get the Package Manager Console open. View | Other Windows | Package Manager Console
Now we want to install the Entity Framework Code First libraries. NuGet makes this very easy:

The console window support auto-completion, so just type Ins [TAB] and a list of options will show. Choose Install-Package then type EFC [TAB] to choose through a list of packages. Couldn’t be easier. I’m not going to go into details about what that does, you can read all about it in ScottGu’s posts and the video of Scott Hanselman’s talk.
In our first post in the series, our first goal was to make a quick site. Doing it quickly means we are going to let the Entity Framework create the database for us. We will also be using SQL CE so there won’t be a full database dependency. SQL CE 4.0 is now bin deployable, so we can just copy it up and it’ll work.
EF, much like MVC, uses convention over configuration. So, since our context (code to follow) is going to be named Cookbook, if we create a connection string entry called Cookbook, EF will automatically use that.
<connectionStrings>
<add name="Cookbook" connectionString="Data Source=|DataDirectory|KimmysCookbook.sdf" providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
As an aside, if you don’t create a connectionstring at all, EF CTP5 will create a Sql Server CE 4.0 database under the App_Data directory for you using the fully qualified type name as the name of the database.
Now for our Context class. We’ll create each of our supporting classes as we go. Right click on the Models folder and add a class. As you are typing, as you put in the classes for the generic collections, pressing Ctrl-. will present you with a context of options. Since the classes won’t exist yet, you can have VS create the classes for you right then. They will of course be empty, but the shell is there. VS is also intelligent enough to put them in the same folder as the current class with the same namespace. So, when you type public DbSet<Recipe, you’ll get a squiggly saying that Recipe doesn’t exist. Ctrl-. and choose to have it create the class for you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace KimmysCookbook.Models
{
public class Cookbook : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Favorite> Favorites { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Rating> Ratings { get; set; }
}
}
The above context class is all that is needed for data access.
Let’s fill in the rest of our classes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KimmysCookbook.Models
{
public class Recipe
{
public int ID { get; set; }
public Guid UserID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public long PrepTime { get; set; }
public long CookTime { get; set; }
public int Serves { get; set; }
public string Instructions { get; set; }
public string IPAddress { get; set; }
public virtual ICollection<Ingredient> Ingredients { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<Rating> Ratings { get; set; }
public virtual ICollection<Favorite> Favorites { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KimmysCookbook.Models
{
public class Ingredient
{
public int ID { get; set; }
public int RecipeID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KimmysCookbook.Models
{
/// <summary>
/// This is for user based tagging
/// </summary>
public class Tag
{
public int ID { get; set; }
public int RecipeID { get; set; }
public Guid UserID { get; set; }
public string Value { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KimmysCookbook.Models
{
public class Comment
{
public int ID { get; set; }
public int RecipeID { get; set; }
public Guid UserID { get; set; }
public string Text { get; set; }
public string IPAddress { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KimmysCookbook.Models
{
/// <summary>
/// This is to tag a recipe as a favorite for a user
/// </summary>
public class Favorite
{
public int ID { get; set; }
public int RecipeID { get; set; }
public Guid UserID { get; set; }
public DateTime DateFavorited { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KimmysCookbook.Models
{
public class Rating
{
public int ID { get; set; }
public int RecipeID { get; set; }
public Guid UserID { get; set; }
public int Value { get; set; }
public DateTime RatingDate { get; set; }
public string IPAddress { get; set; }
}
}
You’ll notice in the classes that the UserID field is a Guid. In this iteration, we are going to use the Membership provider that is baked into asp.net. In a future release, we plan to use OpenID instead. That being said and to keep it simple, we want to have the membership baked into the database that EF is going to create. Unfortunately, SQL CE 4 still doesn’t support stored procedures so the current implementation of membership won’t work with it. According to ScottGu’s post, they are looking into create a set of providers that will work with it.