Like it

Sunday, July 17, 2011

EF Code First and Data Scaffolding with the ASP.NET MVC 3 Tools Update


Earlier this week I blogged about the new ASP.NET MVC 3 Tools Update that we shipped last month. 
In today's blog post I'm going to go into more detail about two of the cool new features it brings:
  1. Built-in support for EF 4.1 (which includes the new EF "code-first" support)
  2. Built-in data scaffolding support within Visual Studio (which enables you to rapidly create data-driven sites)
These two features provide a really sweet, and extremely powerful, way to work with data and build data-driven web applications.

Scenario We'll Build

To help illustrate how to use the above features, we'll walkthrough building a simple data-drive site.  It will support listing products:
SNAGHTML4e066438
As well as creating/editing new products (and categories):
SNAGHTML4e078291
We can now build this entire application (and create the database that backs it) with ASP.NET MVC 3 in only a minute or two.

Step 1: Create New Project

We'll begin by creating a new ASP.NET MVC 3 project (using the File->New Project menu command).  We'll use the "Internet Project" template – which will provide us with a default starter template for our application. 
When you look at the newly created project within the Solution Explorer, you'll see that the ASP.NET MVC 3 Tools update adds a new assembly – EntityFramework – to our ASP.NET MVC 3 projects:
image
The EntityFramework assembly implements Entity Framework 4.1 – which we also released last month.  EF 4.1 brings with it a bunch of great data API improvements to .NET – including the new "code first" option.  EF Code First provides a really elegant and clean way to work with data, and enables you to do so without requiring a designer or XML mapping file.  You can now easily take advantage of this by default with all new ASP.NET MVC 3 projects.
We'll be using the EF Code First approach to implement our data access for this application.

Step 2: Implement Model Classes

Our first step will be to create two classes – Product and Category – that we'll use to define the "model" of our application.  We'll implement these as standard "plain old C# objects" within the \Models folder of our project using the code below:
image
Notice how the above classes are just standard classes with .NET data-types.  They do not need to derive from any base class, nor implement any interfaces. 
In addition to standard scalar properties, each class has an "association" property.  For example, the "Product" class has a "Category" property that enables a developer to get access to the Category it belongs to.  Likewise the "Category" class has a "Products" property that enables a developer to retrieve the Products that are within that particular Category.  EF Code First can handle automatically managing these associations (using the Primary Key/Foreign Key values), and can lazy load the appropriate data on-demand.

Step 3: Implement a StoreContext Class using EF Code First

Now that we've defined our two model classes, our next step will be to implement a "DbContext" class using EF code First that will map the model classes to tables in a database.  We'll implement this using the code below:
SNAGHTML4d35a6ee
The "StoreContext" class above is the DbContext class we are using to map our Product and Category classes to/from a database.  It derives from the DbContext base class provided by EF Code First, and exposes two properties that correspond to tables within our database.  For this sample we are using the default "convention over configuration" based mapping rules to define how the classes should map to/from the database.  This means that the Products property will map to a Products table, and the Categories property will map to a Categories table.  In later blog posts I'll talk about how you can optionally override this and perform custom mappings.
You can add the above class anywhere within your solution.  For example, you could add it within the \Models folder of your project – or within a separate class library project if you prefer to keep your data code separate.  You'll want to add a "using" statement to the System.Data.Entity namespace at the top of the class file (in order to reference the DbContext and DbSet<T> classes).
After you've saved the above class files, compile the project – you'll want to have built it before the next step.

Step 4: Scaffold a Categories Controller

We have everything we need to model our data and save/retrieve it from a database.  Now let's create an ASP.NET MVC Controller class that will implement the support necessary to display our Category data and enable creating/editing/deleting Category objects.  Prior to last month's ASP.NET MVC 3 Tools Update, you would have had to manually write a Controller class to do this (and implement all of the EF data access code yourself).  The ASP.NET MVC 3 Tools Update now includes built-in "scaffolding" support that can help do this for you automatically.
To scaffold a new Categories controller class, we'll right-click on the "/Controllers" folder of our project and choose the Add->Controller context menu:
image
Selecting Add->Controller will bring up the "Add Controller" dialog.  We'll name the controller class we want to create "CategoriesController".  Starting with last month's ASP.NET MVC 3 Tools Update, the "Add Controller" dialog also now supports a new "Scaffolding options" section – which enables you to choose to "scaffold" the new controller using a variety of built-in templates:
image
We'll choose the "Controller with read/write actions and views, using Entity Framework" template – which will create a Controller class that has all of the EF code necessary to create, update, list and delete model objects.
After selecting this template, we can choose the model class we want our Controller to implement CRUD support for – in this case the "Category" class.  We can also select the EF DbContext/ObjectContext class that we want to use to access the database – in this case the "StoreContext" class we defined earlier:
SNAGHTML4d81d687
When we click the "Add" button, Visual Studio will automatically create a CategoriesController class for us – with appropriate Create, Edit, Details, Delete and Index action methods inside it – as well associated view templates for each of the actions:
image
If you open the CategoriesController.cs class you'll find that the action methods within it implement the EF data access code necessary for CRUD support:
image
And now we have all of the code we need to implement data listing/editing for Categories within our database

Step 5: Configuring our Database Location

The last step we'll do before running our application is to point our application at the database we want to use.  EF code first allows you to use an existing database you already have defined, or alternatively you can point it at a database that doesn't yet exist – in which case it will automatically create it for you using the model classes you've defined.
No Connection-String
By default, you actually don't need to configure a connection-string to point at a database.  If you don't specify one, EF Code-First will by default create a new SQL Express database whose name matches your DbContext class name (for example: above it would create a ScaffoldingDemo.Models.StoreContext database within your local .\SQLExpress database instance). 
Explicitly Specifying a Connection-String
You can alternatively explicitly specify where you want your database to live by adding a connection-string to your application's web.config file.  You'll want the name of the connection-string to match the DbContext class name.  For example – in our application above our DbContext class was named "StoreContext", and so by default EF will look for a connection-string with the same name to determine the database location.
Below is the entry we'd add to our web.config file if we wanted to use an embedded SQL CE database named "Store.sdf" within our application's \App_data folder:
<configuration>
      <connectionStrings>
              <add name="StoreContext"
                         connectionString="Data Source=|DataDirectory|\Store.sdf"
                         providerName="System.Data.SqlServerCe.4.0" />
       </connectionStrings>

</configuration>
You can learn more about SQL CE – and the new VS 2010 SP1 tooling support for it – from my previous blog post about it.

Step 6: Run the Application

Ok – let's now run the application and navigate to the /Categories URL.  This will execute our CategoriesController's Index() method – which will list all categories in our database.  Currently we don't have any:
SNAGHTML4dede162
Let's click the "Create New" link to create a new category – this will navigate to the /Categories/Create URL, which provides us with a form to create a new category:
SNAGHTML4def03ef
Clicking the "Create" button will post the form to our CategoriesController and add a new Category to our database.  We can repeat this a few times to add several different categories:
SNAGHTML4df02093
The cool thing is that we didn't have to write any Controller or View code to enable this – the scaffolding support automatically generated the code we needed to enable this.  This provides a really easy way to get started.  We can then go in and tweak it as necessary to customize the functionality further.

Step 7: Looking at the database

We configured our application to use a connection-string that pointed to a SQL CE database that (at the time) didn't exist.  When we ran our application, EF 4.1 detected that the database didn't exist and automatically created it for us – based on the Product and Category classes we defined earlier. 
To see the database, click the "Show All Files" icon at the top of Visual Studio's "Solution Explorer" and add the "Store.sdf" database that was automatically created by EF to your project:
image
You can then double-click the database to open it up in the Server Explorer – and expand the tables within it to see the schema that was created:
image
Notice above how EF Code First automatically created the appropriate database schema based on the Category and Product classes we created earlier.  It also automatically setup Primary Key/Foreign-Key relationships between the two tables based on the association properties specified in the classes.

Step 8: Scaffolding a Products Controller

We've created a CategoriesController class to manage listing and editing Categories.  Let's now create a ProductsController class to manage listing and editing Products.
Just like before, we'll right-click on the \Controllers folder in our project and choose the Add->Controller context menu.  We'll name the Controller class we want to create "ProductsController" and indicate that we want to scaffold using the EF template with a Product model class:
SNAGHTML4dfb7c0b
Clicking the "Add" button will scaffold a ProductsController class for us, with appropriate action methods for CRUD scenarios, and create the associated view templates that go with them:
image
We can then run our project again and navigate to the /Products URL within it:
SNAGHTML4dfeca88
Let's click the "Create New" link to create a new Product:
SNAGHTML4e028a2f
One cool thing to notice is that the "Category" is a drop-down of valid Categories (and not just a textbox with a foreign-key integer value):
image
The scaffolding support within Visual Studio was smart enough to detect that Category was an association, and scaffold EF code that populates the drop-down with valid Categories.
After entering several products our /Products URL will display the data like below:
SNAGHTML4e066438
Notice again how Category is displayed using the friendly name – and not just the foreign-key value.

Learning More

The above walkthrough provided a quick look at the new EF code-first and data scaffolding support built-into the ASP.NET MVC 3 Tools Update, and how you can use them to easily and quickly jumpstart application development.  EF Code First enables you to write incredibly clean data access code.  The data scaffolding support enables you to rapidly create data UI – and then allows you to go in and easily tweak/customize it further.
In addition to working with EF Code-First, you can also use the data scaffolding support against standard EF ObjectContext objects (built using either the database-first or model-first approach and the EF WYSIWYG designer).
Scaffolding
You can learn more about the new ASP.NET MVC 3 Scaffolding Support from Steve Sanderson's excellent talk about it at MIX:
In his talk Steve also covers how you can use the scaffolding support from the command-line (using NuGet) as well as how you can download and use additional scaffolding templates (for example: ones that can automatically implement a repository pattern, etc).  Also make sure you bookmark Steve's excellent blog series about scaffolding (and its extensibility) here:
EF Code First
I'll be doing more blog posts about EF Code First in the future.  Below are links to some tutorials I've written in the past about it:
Note: The above tutorials were written against the CTP4 release of EF Code First (and so some APIs are a little different) – but the concepts and scenarios outlined in them are the same as with the final release.
ASP.NET MVC 3
If you want to learn more about ASP.NET MVC 3, I highly recommend Scott Hanselman's excellent video presentations at the Dutch DevDays and at MIX:
Also check out all of the new content and videos on the http://asp.net/mvc web-site:

Summary

The new ASP.NET MVC 3 Tooling Update is full of goodness.  If you haven't already downloaded and installed it I highly recommend you do so.  Stay tuned for even more blog posts about it!
Hope this helps,
Scott
P.S. I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu

No comments:

Post a Comment