So far all of our little example applications have consisted of a single project. Of course, that’s not the way most applications are built, and one of the things that the Code-First Workflow simplifies is n-tier development. You would typically include (at least) three projects in your application:
When you use the Code-First Workflow, your data model—the classes that represent the entities themselves—are just classes. Among other things, that makes testing easier because with the exception of data annotations (and you don’t necessarily need those, as we’ll see), they have nothing to do with the Entity Framework. (Technically, they’re PERSISTENCE-IGNORANT POCOS).
Not to be confused with a data access layer (although it will be a key component of the DAL), the data access project links the model to the user interface. This project does need the Entity Framework NuGet package and a reference to the model project.
At a minimum, the data access project will define a concrete DbContext
that contains DbSet<>
properties for each of the primary entities in the data model project.
The exact nature of this project will, of course, depend on the UI platform and architecture you choose for your application, but this is where you’ll instantiate your context and manipulate the data. You might include the data manipulation directly in the project with the UX, or you might use a separate project if, for example, you’re using MVVM. But that’s an architectural issue that’s outside the scope of our discussion.
Whatever your architecture, the data client project will need to have the Entity Framework NuGet package and references to both the model and data access projects.
Put On Your Thinking Hat
I think you’ll be surprised at how easy it is to build an Entity Framework application using the Code-First Workflow, so let’s get started:
Create a new console application project. We won’t be using it just yet, but creating it first makes it the start-up project. (I always forget to do that later. At least, until I press F5 the first time...) Make sure you change the solution name to something sensible. I called the project CodeFirstConsole
and the solution CodeFirstRecipe
.
Add a class library to the solution (I called mine CodeFirstModel
) and create the three recipe classes. (You can delete the Class1
file that Visual Studio creates for you.) These are just straight .NET classes; No Entity Framework stuff required.
Make sure to make your class and property definitions public.
Add a second class library to the solution. (I called mine CodeFirstDataAccess.
) Add the NuGet package to this one, and a reference to the model project. This one needs just a single class (I called mine RecipeContext
) that descends from DbContext
and contains a single property, a DbSet<Recipe>
called Recipes
. You’ll need to add a using
(C#) or Imports
(VB) statement to the top of the class file to reference System.Data.Entity
(to get access to the DbContext
and DbSet<>
classes) and CodeFirstModel
(to get access to the Recipe
class).
Put On Your Thinking Hat
Whew, that was a lot of code without much help from me, wasn’t it?
Your solution should look like this.
Here’s the Context class.
public class Recipe
{
public int RecipeId { get; set; }
public string RecipeName { get; set; }
public string Source { get; set; }
public string Headnote { get; set; }
public List<RecipeStep> Steps { get; set; }
`public List<RecipeIngredient> Ingredients { get; set; }
}
And here are the other class definitions.
public class RecipeIngredient
{
public int RecipeIngredientId { get; set; }
public decimal Amount { get; set; }
public string Unit { get; set; }
public string Preparation { get; set};
}
public class RecipeStep
{
public int RecipeStepId { get; set; }
public string Text { get; set; }
}
Put On Your Thinking Hat
Whew, that was a lot of code without much help with me, wasn’t it?
Here’s the Context class.
Public Class Recipe
Public Property RecipeId As Integer
Public Property RecipeName As String
Public Property Source As String
Public Property Headnote As String
Public Property Steps As List(Of RecipeStep)
Public Property Ingredients As List(Of RecipeIngredient)
End Class
And here are the other class definitions.
Public Class RecipeIngredient
Public Property RecipeIngredientID As Integer
Public Property Amount As Decimal
Public Property Unit As String
Public Property Preparation As String
End Class
Public Class RecipeStep
Public Property RecipeStepID As Integer
Public Property Text As String
End Class