Sunday, June 26, 2016

Entity Framework Core InMemory Provider

[Please note that this post discusses the topic in the context of ASP.NET Core 1.0 RC2 and Entity Framework Core RC2]

With Entity Framework 7 or rather Entity Framework Core there is this new Database Provider which is InMemory. The use of this is basically for Testing. For instance in your Unit Tests rather than connecting to the actual database which causes additional overhead, you can use the InMemory option. In this post let’s see how you can configure EF Core InMemory provider within an ASP.NET Core Application.

Let’s kick off Visual Studio and create a ASP.NET Core Web Application. Once the project is created, you need to install “Microsoft.EntityFrameworkCore.InMemory” nuget package. The newest way to do that is open up project.json and under dependencies add the following. Alternatively you can use Nuget and carry out the same old process.
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0-rc2-final"
The version here can be what ever the latest (I suggest you use the latest, as these are in RC, they will get change over time). As of today it’s “1.0.0-rc2-final” and I am sure it’s going to be updated really soon.

Once all the packages are restored, let’s create a folder named “Models” and inside that folder, add two classes, one for demo Entity/Model and one for the DbContext.

Employee.cs
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}
MyDbContext.cs
using Microsoft.EntityFrameworkCore;
 
public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
    {
    }
 
    public DbSet<Employee> Employees { get; set; }
}
Next open up Startup.cs and let’s configure the MyDbContext as an InMemory provider. For that let’s modify the ConfigureServices method adding the following line.
services.AddDbContext<MyDbContext>(options => options.UseInMemoryDatabase());
Now I am all set. Let’s add a new Controller to the “Controllers” folder to manage Employees.

EmployeesController.cs
namespace EFCoreInMemoryDemo.Controllers
{
    using EFCoreInMemoryDemo.Models;
    using Microsoft.AspNetCore.Mvc;
    using System.Linq;
 
    [Route("api/[controller]")]
    public class EmployeesController : Controller
    {
        private MyDbContext dbContext;
 
        public EmployeesController(MyDbContext dbContext)
        {
            this.dbContext = dbContext;
        }
 
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(this.dbContext.Employees.ToList());
        }
 
        [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok(this.dbContext.Employees.FirstOrDefault(e => e.Id == id));
        }
 
        [HttpPost]
        public IActionResult Post([FromBody]Employee employee)
        {
            this.dbContext.Employees.Add(employee);
            this.dbContext.SaveChanges();
            return Created("Get", employee);
        }
    }
}
Here in the EmployeesController constructor, I have injected MyDbContext and it is used through out the controller actions. I don’t think I need to explain all the code here, basically it’s what we have been using all this time. One interesting thing though.
  • RouteToken
SNAGHTMLddc746b
RouteToken
Basically the advantage of having a Route Token is in case we renamed the controller name, if we have like “api/employees” the string won’t get refactored.

Now let’s just run the application and see how it works. You can either use Postman, Fiddler, or even configure Swagger to send a POST request here.

First let's send a GET request to see all the employees.

image
GET All Employees
It's obvious, we didn't send any POST requests to create employees before. So we are returned with empty list. Now let's send a POST request to create an Employee. Here I am using Postman.
image
POST Employee
As you can see Status is 201 which is what I have returned from my POST action upon successful creation of employee. Now if you GET all employees, you can see the employee information we just created.

image
GET All Employees
I am doing another POST to create another employee and if we send a GET to see all the employees now, it's there.

image
GET All Employees
Now to see the actual meaning of InMemory provider, if you restarted the debug session and send a GET to list all employees, there is none.

image
GET All Employees
Hope you got the basic idea behind EF Core InMemory Provider.

Happy Coding.

Regards,
Jaliya