joydip_kanjilal
Contributor

How to use EF Core as an in-memory database in ASP.NET Core 6

how-to
Sep 08, 20229 mins
C#Development Libraries and FrameworksMicrosoft .NET

Entity Framework Core allows you to store and retrieve data to and from an in-memory database. It’s a quick and easy way to test your ASP.NET Core 6 web applications.

A leaping dog catches a flying disc, midair.
Credit: Cerae / Getty Images

There are many reasons why you might want to use an in-memory database when working on ASP.NET Core 6 web applications. Maybe you’re developing a new feature and you want to test it without affecting your production database. Or perhaps you want a quick way to prototype something without setting up a whole new database.

Entity Framework Core, or EF Core for short, simplifies data access in .NET Core applications and allows you to write code to perform CRUD (create, read, update, delete) operations without directly interacting with the underlying database provider. The EF Core In-Memory Database Provider allows us to use EF Core with an in-memory database for testing.

The EF Core In-Memory Database Provider lets us store and retrieve data to and from memory in .NET Core 6 applications. Just remember that this provider was designed for testing purposes only.

This article discusses how we can use EF Core with an in-memory database in an ASP.NET Core 6 application. To work with the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core project in Visual Studio 2022. Following these steps will create a new ASP.NET Core 6 Web API project in Visual Studio 2022:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, select .NET 6.0 as the target framework from the drop-down list at the top. Leave the “Authentication Type” set to “None” (default).
  9. Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are unchecked as we won’t be using any of those features here.
  10. Click Create.

We’ll use this ASP.NET Core 6 Web API project to work with EF Core and an in-memory database in the subsequent sections of this article.

What is EF Core? When should we use it?

EF Core is a lightweight, open-source, extensible ORM (Object Relational Mapper) that supports several database providers including SQLite, MySQL, PostgreSQL, and Microsoft SQL Server. (You’ll find a complete list of EF Core providers here.) And, as we’ve noted, EF Core supports storing and retrieving data to and from memory using its In-Memory Database Provider.

EF Core also supports LINQ (Language Integrated Query), which makes it easier to write queries against the data in your database. This is because LINQ allows you to write queries directly in C# instead of SQL or some other query language.

The ability to store and retrieve data in memory using the EF Core In-Memory Database Provider is especially well-suited for testing apps or for building applications that need to store data temporarily. And because an in-memory database is both fast and fast to set up, it is very handy to use one for unit testing.

What is an in-memory database?

An in-memory database is a database that resides in volatile memory instead of on a physical disk. Naturally, reads and writes for an in-memory database are many times faster than for a disk-based database, because the application need not wait for the data to be physically written to or read from the disk. Reading and writing data stored on a physical disk is a resource-intensive operation.

In-memory databases are often used for caching purposes, as they can hold a copy of often-used data in memory for quick access. You can also take advantage of in-memory databases to store transient data, i.e., data that does not need to be persisted to the disk.

There are also some notable downsides to using an in-memory database, though these apply to production use and not our testing scenario. One of these is that if you’re using an in-memory database, the data will not be persisted when the application stops running (unless you take steps to persist it). This means that if the application crashes, all of the data residing in the in-memory database will be lost.

Another downside is that an in-memory database uses much more memory compared to a traditional database that resides on a physical disk (and memory is far more expensive than disk storage). As a result, an in-memory database may not be suitable for applications that deal with vast amounts of data. But again, these downsides don’t really apply to using an in-memory database for testing.

Using an in-memory database in ASP.NET Core 6

In this section we’ll examine how we can use an in-memory database to store and retrieve data in an ASP.NET Core 6 application. We’ll follow these steps to create and use an in-memory database in ASP.NET Core 6:

  1. Install the EF Core InMemory NuGet package
  2. Create a new custom DbContext class
  3. Create the model classes
  4. Create the Repository class
  5. Add the Repository as a service to the container
  6. Create a new controller
  7. Use dependency injection in the controller to access the Repository instance
  8. Execute the application

Let’s get started!

Install the EF Core InMemory NuGet package

To leverage the in-memory capabilities of EF Core in your application, you should add the Microsoft.EntityFrameworkCore.InMemory package to your project. To do this, select the project in the Solution Explorer window, then right-click and select “Manage NuGet Packages.” In the NuGet Package Manager window, search for the Microsoft.EntityFrameworkCore.InMemory package and install it.

Alternatively, you can install the package via the NuGet Package Manager console by entering the command shown below.

PM> Install-Package Microsoft.EntityFrameworkCore.InMemory

Create a custom DbContext class in ASP.NET Core 6

In EF Core, the DbContext is used by the application to interact with the underlying database. Before we proceed, let’s create a custom DbContext class that we’ll use to extend the DbContext class of the EF Core framework.

using EFCoreInMemoryDbDemo.Models;
using Microsoft.EntityFrameworkCore;
namespace EFCoreInMemoryDbDemo
{
    public class ApiContext : DbContext
    {
        protected override void OnConfiguring
       (DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseInMemoryDatabase(databaseName: "AuthorDb");
        }
        public DbSet<Author> Authors { get; set; }
        public DbSet<Book> Books { get; set; }
    }
}

Note how we have specified the name of the in-memory database in the OnConfiguring method.

Create model classes in ASP.NET Core 6

We’ll use two simple model classes for working with data in this application. These model classes are Author and Book. Create a new .cs file named Author.cs and enter the following code:

    public class Author
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Book> Books { get; set; }
    }

Create another .cs file named Book.cs and give it the following code:

    public class Book
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public Author Author { get; set; }
    }

Create a Repository class in ASP.NET Core 6

Create an interface named IAuthorRepository in a file having the same name with a .cs extension and write the following code in there:

public interface IAuthorRepository
{
    public List<Author> GetAuthors();
}

The AuthorRepository class implements the members of the IAuthorRepository interface as shown in the code listing given below.

using EFCoreInMemoryDbDemo.Models;
using Microsoft.EntityFrameworkCore;
namespace EFCoreInMemoryDbDemo
{
    public class AuthorRepository : IAuthorRepository
    {
        public AuthorRepository()
        {
            using (var context = new ApiContext())
            {
                var authors = new List<Author>
                {
                new Author
                {
                    FirstName ="Joydip",
                    LastName ="Kanjilal",
                       Books = new List<Book>()
                    {
                        new Book { Title = "Mastering C# 8.0"},
                        new Book { Title = "Entity Framework Tutorial"},
                        new Book { Title = "ASP.NET 4.0 Programming"}
                    }
                },
                new Author
                {
                    FirstName ="Yashavanth",
                    LastName ="Kanetkar",
                    Books = new List<Book>()
                    {
                        new Book { Title = "Let us C"},
                        new Book { Title = "Let us C++"},
                        new Book { Title = "Let us C#"}
                    }
                }
                };
                context.Authors.AddRange(authors);
                context.SaveChanges();
            }
        }
        public List<Author> GetAuthors()
        {
            using (var context = new ApiContext())
            {
                var list = context.Authors
                    .Include(a => a.Books)
                    .ToList();
                return list;
            }
        }
    }
}

Note how the custom DbContext we created earlier is used in the AuthorRepository class to store and retrieve data to and from the in-memory database.

Add the Repository service to the services container in ASP.NET Core 6

To use dependency injection in your controllers or other classes in your project, you must add the services to the dependency injection container.

Add the following line of code in the Program.cs file to add the AuthorRepository service to the container.

builder.Services.AddScoped<IAuthorRepository, AuthorRepository>();

Here is the complete source code of the Program.cs file for your reference:

using EFCoreInMemoryDbDemo;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IAuthorRepository, AuthorRepository>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

Create a Web API controller in ASP.NET Core 6

So far so good. Now, right-click on the Controllers solution folder, click “Add -> Controller…”, and create a new API controller in your project. Name the controller AuthorController and replace the default generated code with the following:

using EFCoreInMemoryDbDemo.Models;
using Microsoft.AspNetCore.Mvc;
namespace EFCoreInMemoryDbDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthorController : ControllerBase
    {
        readonly IAuthorRepository _authorRepository;
        public AuthorController(IAuthorRepository authorRepository)
        {
            _authorRepository = authorRepository;
        }
        [HttpGet]
        public ActionResult<List<Author>> Get()
        {
            return Ok(_authorRepository.GetAuthors());
        }
    }
}

Note how dependency injection has been used to inject an instance of type IAuthorRepository in the constructor of the AuthorController class. The HttpGet action method of the AuthorController class calls the GetAuthors method of the AuthorRepository class and returns a list of authors.

Finally, when you execute the application and hit the HttpGet endpoint of the AuthorController using Postman, you should see the output as shown in Figure 1 below.

ef core in memory database 01 IDG

Figure 1. Testing our simple in-memory database created with ASP.NET Core 6 and EF Core.

This was a minimalistic implementation of an ASP.NET Core 6 web application with the primary intent of showing you how to work with an in-memory database using EF Core. You should write your own custom code to generate the Ids for both of the model classes. Additionally, you might take advantage of unit tests to test the endpoints in your application. As you might expect, unit tests that leverage the EF Core In-Memory Database Provider will run quite fast.

joydip_kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author