This is the fourth part in a multiple part blog series on building ASP.NET 5 (ASP.NET vNext) apps with AngularJS. In this series of blog posts, I show how you can create a simple Movie app using ASP.NET 5, MVC 6, and AngularJS.
- ASP.NET 5 and AngularJS Part 1, Grunt, Uglify, and AngularJS
- ASP.NET 5 and AngularJS Part 2, Using the MVC 6 Web API
- ASP.NET 5 and AngularJS Part 3, Adding Client Routing
- ASP.NET 5 and AngularJS Part 4, Using Entity Framework 7
- ASP.NET 5 and AngularJS Part 5, Form Validation
- ASP.NET 5 and AngularJS Part 6, Security
- ASP.NET 5 and AngularJS Part 7, Running on a Mac
You can download the code discussed in this blog post from GitHub:
https://github.com/StephenWalther/MovieAngularJSApp
In this blog post, I explain how to use Entity Framework 7 to persist the movie data to a database.
Adding the Entity Framework NuGet Packages
Before you can use the Entity Framework, you must add the Entity Framework 7 NuGet packages to your project. Ensure that your project.json file includes the following two dependencies (you’ll get Intellisense while entering the names of the packages and their versions).
"EntityFramework.SqlServer": "7.0.0-beta2", "EntityFramework.Commands": "7.0.0-beta2",
After you complete this step, the Entity Framework packages should appear under References:
Creating the Model and DbContext
Next, we need to create our Movie model class. This class represents the entity that we want to store in the database. Add the following Movie.cs class to your Models folder:
namespace MovieAngularJSApp.Models { public class Movie { public int Id { get; set; } public string Title { get; set; } public string Director { get; set; } } }
We also need to create an Entity Framework DbContext class. We create this class when using Entity Framework 7 in exactly the same way as we created this class for previous versions of the Entity Framework.
using Microsoft.Data.Entity; namespace MovieAngularJSApp.Models { public class MoviesAppContext:DbContext { public DbSet<Movie> Movies { get; set; } } }
Registering the Entity Framework Services
Now that we have our DbContext class, we need to register the DbContext with our application services. Modify your Startup.cs file so it contains the code for registering the Entity Framework in the code below:
using Microsoft.AspNet.Builder; using Microsoft.Framework.DependencyInjection; using Microsoft.Data.Entity; using MovieAngularJSApp.Models; using Microsoft.AspNet.Hosting; using Microsoft.Framework.ConfigurationModel; namespace MovieAngularJSApp { public class Startup { public Startup(IHostingEnvironment env) { // Setup configuration sources. Configuration = new Configuration() .AddJsonFile("config.json") .AddEnvironmentVariables(); } public IConfiguration Configuration { get; set; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); // Register Entity Framework services.AddEntityFramework(Configuration) .AddSqlServer() .AddDbContext<MoviesAppContext>(); } public void Configure(IApplicationBuilder app) { app.UseMvc(); } } }
The database connection string is loaded up from the Config.json file (notice the constructor in the Startup.cs file). Here is what the Config.json file looks like:
{ "Data": { "DefaultConnection": { "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=MoviesDatabase;Trusted_Connection=True;MultipleActiveResultSets=true" } }, "EntityFramework": { "MoviesAppContext": { "ConnectionStringKey": "Data:DefaultConnection:ConnectionString" } } }
Updating the MoviesController
Because we registered our MoviesAppContext class as a service, we can take advantage of the built-in ASP.NET 5 Dependency Injection framework to use the MoviesAppContext in our MoviesController. Notice that the MoviesAppContext class is added to the MoviesController using constructor dependency injection in the code below:
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Mvc; using MovieAngularJSApp.Models; namespace MovieAngularJSApp.API.Controllers { [Route("api/[controller]")] public class MoviesController : Controller { private readonly MoviesAppContext _dbContext; public MoviesController(MoviesAppContext dbContext) { _dbContext = dbContext; } [HttpGet] public IEnumerable<Movie> Get() { return _dbContext.Movies; } [HttpGet("{id:int}")] public IActionResult Get(int id) { var movie = _dbContext.Movies.FirstOrDefault(m => m.Id == id); if (movie == null) { return new HttpNotFoundResult(); } else { return new ObjectResult(movie); } } [HttpPost] public IActionResult Post([FromBody]Movie movie) { if (movie.Id == 0) { _dbContext.Movies.Add(movie); _dbContext.SaveChanges(); return new ObjectResult(movie); } else { var original = _dbContext.Movies.FirstOrDefault(m => m.Id == movie.Id); original.Title = movie.Title; original.Director = movie.Director; _dbContext.SaveChanges(); return new ObjectResult(original); } } [HttpDelete("{id:int}")] public IActionResult Delete(int id) { var movie = _dbContext.Movies.FirstOrDefault(m => m.Id == id); _dbContext.Movies.Remove(movie); _dbContext.SaveChanges(); return new HttpStatusCodeResult(200); } } }
Performing Database Migrations
After we complete all of the steps above, our application still won’t work. If we run the Movies app then we will get an error message about not being able to open the MoviesDatabase.
Unlike previous versions of the Entity Framework, the Entity Framework 7 does not support database initializers. Instead, you are encouraged to use Database Migrations.
There are two ways to use Migrations with ASP.NET 5: from a Command Prompt or from the NuGet Package Manager Console. You can read the details about each approach by reading Brice Lam’s blog at the following addresses:
http://bricelam.net/2014/10/22/ef7-nuget-commands.html
http://bricelam.net/2014/09/14/migrations-on-k.html
Here, I used the Command Prompt approach and I executed the following two commands from the same directory that contains my project.json file:
k ef migration add initial k ef migration apply
After you execute the two ef commands above, a new database named MoviesDatabase will be created. You can see the new database by opening up the Visual Studio SQL Server Object Explorer:
Executing the ef commands above will also add a new Migrations folder to your project.
You now should be able to run the Movies app successfully. When you click the Add button, you should be able to add a new movie to the database. You also should be able to edit and delete movies.
Summary
In this blog post, I focused on using ASP.NET 5 with Entity Framework 7. I explained how you can add the NuGet packages for Entity Framework 7 and register the Entity Framework services in your Startup.cs file. Finally, I showed you how to use Migrations to initialize a new database.
In the next blog post, I will focus on the topic of client-side and server-side validation.
Probably a stupid question but I am not sure how to get the “k” command working on command prompt. Those two links didn’t fully help either. Do I need to install something?
@ARD — The K command line tool is installed automatically when you install VS 2015. Alternatively, you can download and install with powershell without installing VS 2015. There are instructions here https://github.com/aspnet/Home
Thanks. Its working now.
System.InvalidOperationException: No service for type ‘Microsoft.Data.Entity.Inf
rastructure.DbContextService`1[Microsoft.Data.Entity.Migrations.Infrastructure.M
igrator]’ has been registered.
k ef migration initial
is throwing the error
System.InvalidOperationException: No service for type ‘Microsoft.Data.Entity.Inf
rastructure.DbContextService`1[Microsoft.Data.Entity.Migrations.Infrastructure.M
igrator]’ has been registered.