.NET 6.0 - Connect to InMemory Database with Entity Framework Core
Tutorial built with .NET 6.0
This post shows how to connect a .NET 6 API to an InMemory database for testing with Entity Framework Core.
The example code is from of a .NET 6 CRUD API tutorial I posted recently that uses the EF Core InMemory db provider. For full details about the .NET CRUD API see .NET 6.0 - CRUD API Example and Tutorial.
When the API is started it automatically creates a database in memory so the API can be tested without needing a real database like SQL Server, MySQL, PostgreSQL etc. It's only meant for testing because the in memory database is destroyed when the API is stopped.
Tutorial Contents
- Tools required for this tutorial
- Download & Run the example .NET API
- .NET Code to Connect to InMemory Database
- How to Connect to a Real Database
Tools required for this tutorial
To follow the steps in this tutorial you'll need the following:
- .NET SDK - includes the .NET runtime and command line tools.
- Visual Studio Code - code editor that runs on Windows, Mac and Linux. If you have a different preferred code editor that's fine too.
- C# extension for Visual Studio Code - adds support to VS Code for developing .NET applications.
Download & Run the example .NET API
Follow these steps to download and run the .NET 6 CRUD API on your local machine with the default EF Core InMemory database:
- Download or clone the tutorial project code from https://github.com/cornflourblue/dotnet-6-crud-api
- Start the api by running
dotnet run
from the command line in the project root folder (where the WebApi.csproj file is located), you should see the messageNow listening on: http://localhost:4000
. - You can test the API directly with a tool such as Postman or hook it up with the example Angular or React app available.
Starting in debug mode
You can also start the application in debug mode in VS Code by opening the project root folder in VS Code and pressing F5 or by selecting Debug -> Start Debugging from the top menu, running in debug mode allows you to attach breakpoints to pause execution and step through the application code. For detailed instructions including a short demo video see VS Code + .NET - Debug a .NET Web App in Visual Studio Code.
.NET Code to Connect to InMemory Database
Below are the files responsible for connecting to the in memory database and performing CRUD operations.
.NET 6 Web Api csproj
The csproj (C# project) is an MSBuild based file that contains target framework and NuGet package dependency information for the application.
The package required to use the EF Core InMemory database provider is Microsoft.EntityFrameworkCore.InMemory
. The provider is configured in the data context.
For more info on the C# project file see .NET + MSBuild - C# Project File (.csproj) in a Nutshell.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.3" />
</ItemGroup>
</Project>
Data Context
The data context class is used for accessing application data through Entity Framework. It derives from the Entity Framework DbContext
class and has a public Users
property for accessing and managing user data. The data context is used by the user service for handling all low level data (CRUD) operations.
options.UseInMemoryDatabase()
configures Entity Framework to create and connect to an in-memory database so the API can be tested without a real database.
namespace WebApi.Helpers;
using Microsoft.EntityFrameworkCore;
using WebApi.Entities;
public class DataContext : DbContext
{
protected readonly IConfiguration Configuration;
public DataContext(IConfiguration configuration)
{
Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// in memory database used for simplicity, change to a real db for production applications
options.UseInMemoryDatabase("TestDb");
}
public DbSet<User> Users { get; set; }
}
User Service
The user service is responsible for all database interaction and core business logic related to user CRUD operations.
The top of the file contains an interface that defines the user service, just below that is the concrete user service class that implements the interface and interacts with the EF Core InMemory database.
namespace WebApi.Services;
using AutoMapper;
using BCrypt.Net;
using WebApi.Entities;
using WebApi.Helpers;
using WebApi.Models.Users;
public interface IUserService
{
IEnumerable<User> GetAll();
User GetById(int id);
void Create(CreateRequest model);
void Update(int id, UpdateRequest model);
void Delete(int id);
}
public class UserService : IUserService
{
private DataContext _context;
private readonly IMapper _mapper;
public UserService(
DataContext context,
IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public IEnumerable<User> GetAll()
{
return _context.Users;
}
public User GetById(int id)
{
return getUser(id);
}
public void Create(CreateRequest model)
{
// validate
if (_context.Users.Any(x => x.Email == model.Email))
throw new AppException("User with the email '" + model.Email + "' already exists");
// map model to new user object
var user = _mapper.Map<User>(model);
// hash password
user.PasswordHash = BCrypt.HashPassword(model.Password);
// save user
_context.Users.Add(user);
_context.SaveChanges();
}
public void Update(int id, UpdateRequest model)
{
var user = getUser(id);
// validate
if (model.Email != user.Email && _context.Users.Any(x => x.Email == model.Email))
throw new AppException("User with the email '" + model.Email + "' already exists");
// hash password if it was entered
if (!string.IsNullOrEmpty(model.Password))
user.PasswordHash = BCrypt.HashPassword(model.Password);
// copy model to user and save
_mapper.Map(model, user);
_context.Users.Update(user);
_context.SaveChanges();
}
public void Delete(int id)
{
var user = getUser(id);
_context.Users.Remove(user);
_context.SaveChanges();
}
// helper methods
private User getUser(int id)
{
var user = _context.Users.Find(id);
if (user == null) throw new KeyNotFoundException("User not found");
return user;
}
}
How to Connect to a Real Database
For instructions on how to update the CRUD API to connect to a real database see the below posts:
- SQL Server: .NET 6.0 - Connect to SQL Server with Entity Framework Core
- PostgreSQL: .NET 6.0 - Connect to PostgreSQL Database with Entity Framework Core
- MySQL: .NET 6.0 - Connect to MySQL Database with Entity Framework Core
- SQLite: .NET 6.0 - Connect to SQLite Database with Entity Framework Core
Need Some .NET Help?
Search fiverr for freelance .NET developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!