Entity Framework Core InMemory Database

In this article, we will see how we can use the InMemory database of Entity Framework Core.

In any system, we need master data which is not going to be changed frequently but is mandatory to maintain, in order to run the system smoothly. For example, in an E-commerce website, the product category is required frequently while traversing the site or referring to the product. And such data is not modified often. Now, assume that whenever the category is required, you fetch it from the database and pass it to the site. Well, that becomes a more expensive call. So, as a partial solution, we can keep it in memory so that we can avoid the database call. Microsoft has provided InMemory database with Entity Framework Core.

Let’s see its step by step implementation in .NET Core Web API.

Open Visual Studio and create a new project. Select the API and click the OK button.

Entity Framework Core InMemory Database 

In order to use InMemory database, we need to install a NuGet package, i.e., Microsoft.EntityFrameworkCore.InMemory.

Entity Framework Core InMemory Database 

Create a model for Category. This model will be having fields like Id and CategoryName. Please make sure that the Id column is added in each model.

  1. namespace EFCoreInMemory  
  2. {  
  3.     public class Category  
  4.     {  
  5.         public int  Id { getset; }  
  6.         public string CategoryName { getset; }  
  7.     }  
  8. }  

Create a class called ApiContext which inherits from DbContext.

Declare the public property of type DbSet for Category.

From the parameterized constructor, you can load categories. This data can be loaded from the database, but for demo purposes, I have added hardcoded ones.

Also, create a GetCategories method which returns the list of categories from DbSet.

  1. using Microsoft.EntityFrameworkCore;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4.   
  5. namespace EFCoreInMemory  
  6. {  
  7.     public class ApiContext : DbContext  
  8.     {  
  9.         public DbSet<Category> Categories { getset; }  
  10.   
  11.         public ApiContext(DbContextOptions options) : base(options)  
  12.         {  
  13.             LoadCategories();  
  14.         }  
  15.   
  16.         public void LoadCategories()  
  17.         {  
  18.             Category category = new Category() { CategoryName = "Category1" };  
  19.             Categories.Add(category);  
  20.             category = new Category() { CategoryName = "Category2" };  
  21.             Categories.Add(category);  
  22.         }  
  23.   
  24.         public List<Category> GetCategories()  
  25.         {  
  26.             return Categories.Local.ToList<Category>();  
  27.         }  
  28.     }  
  29. }  

Inject ApiContext to the CategoryController via constructor.

Create a GET method which will call GetCategories of ApiContext and return the data.

  1. using Microsoft.AspNetCore.Mvc;  
  2. using System.Collections.Generic;  
  3. using System.Threading.Tasks;  
  4.   
  5. namespace EFCoreInMemory.Controllers  
  6. {  
  7.     [Route("api/Category")]  
  8.     public class CategoryController : Controller  
  9.     {  
  10.         private readonly ApiContext apiContext;  
  11.   
  12.         public CategoryController(ApiContext apiContext)  
  13.         {  
  14.             this.apiContext = apiContext;  
  15.         }  
  16.   
  17.         // GET api/values  
  18.         [HttpGet]  
  19.         public async Task<IActionResult> Get()  
  20.         {  
  21.             List<Category> categories = apiContext.GetCategories();  
  22.             return Ok(categories);  
  23.         }  
  24.     }  
  25. }  

Configure ApiContext in the startup class with the option UseInMemoryDatabase.

  1. using Microsoft.AspNetCore.Builder;  
  2. using Microsoft.AspNetCore.Hosting;  
  3. using Microsoft.EntityFrameworkCore;  
  4. using Microsoft.Extensions.Configuration;  
  5. using Microsoft.Extensions.DependencyInjection;  
  6.   
  7. namespace EFCoreInMemory  
  8. {  
  9.     public class Startup  
  10.     {  
  11.         public Startup(IConfiguration configuration)  
  12.         {  
  13.             Configuration = configuration;  
  14.         }  
  15.   
  16.         public IConfiguration Configuration { get; }  
  17.   
  18.         public void ConfigureServices(IServiceCollection services)  
  19.         {  
  20.             services.AddDbContext<ApiContext>(opt => opt.UseInMemoryDatabase());  
  21.             services.AddScoped<ApiContext>();  
  22.   
  23.             services.AddMvc();  
  24.         }  
  25.   
  26.         public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
  27.         {  
  28.             if (env.IsDevelopment())  
  29.             {  
  30.                 app.UseDeveloperExceptionPage();  
  31.             }  
  32.   
  33.             app.UseMvc();  
  34.         }  
  35.     }  
  36. }  

Now, run the application and you will be able to see all the added categories. Here, if you observe the result closely, you can see that the Id is added like 1 and 2. But while loading the categories, we have set the CategoryName only; then how it will be added? So, if you remember, at the time of designing a model, I mentioned you should make sure the Id column is added. An InMemory database internally keeps Id and behaves like AutoIncrement feature of SQL. For example, when you add 10 categories the first time, then the Id is given from 1 to 10. Now, if you remove any of the categories in between 1 to 10, (let’s say we are removing category 6) and again you will add the same category, it will get a new Id assigned. (Category Id 6 will be 11 now). This means once you remove the row, Id cannot be reset automatically.

Entity Framework Core InMemory Database 

You can download the sample code from here.