Существует множество причин, по которым вам может потребоваться использовать базу данных в памяти при работе с веб-приложениями ASP.NET Core 6. Возможно, вы разрабатываете новую функцию и хотите протестировать ее, не затрагивая рабочую базу данных. Или, возможно, вам нужен быстрый способ создать прототип чего-либо без создания совершенно новой базы данных.
Entity Framework Core, или сокращенно EF Core, упрощает доступ к данным в приложениях .NET Core и позволяет писать код для выполнения операций CRUD (создание, чтение, обновление, удаление) без прямого взаимодействия с базовым поставщиком базы данных. Поставщик базы данных EF Core в памяти позволяет нам использовать EF Core с базой данных в памяти для тестирования.
Поставщик базы данных EF Core In-Memory позволяет нам хранить и извлекать данные в память и из памяти в приложениях .NET Core 6. Просто помните, что этот провайдер был разработан только в целях тестирования.
В этой статье обсуждается, как мы можем использовать EF Core с базой данных в памяти в приложении ASP.NET Core 6. Для работы с примерами кода, представленными в этой статье, в вашей системе должна быть установлена Visual Studio 2022. Если у вас еще нет копии, вы можете скачать Visual Studio 2022 здесь.
Создайте проект веб-API ASP.NET Core в Visual Studio 2022.
Прежде всего давайте создадим проект ASP.NET Core в Visual Studio 2022. Выполнение этих шагов позволит создать новый проект веб-API ASP.NET Core 6 в Visual Studio 2022:
- Запустите интегрированную среду разработки Visual Studio 2022.
- Нажмите «Создать новый проект».
- В окне «Создать новый проект» выберите «ASP.NET Core Web API» из списка отображаемых шаблонов.
- Нажмите “Далее.
- В окне «Настроить новый проект» укажите имя и местоположение нового проекта.
- При желании установите флажок «Поместить решение и проект в один каталог», в зависимости от ваших предпочтений.
- Нажмите “Далее.
- В показанном ниже окне «Дополнительная информация» выберите .NET 6.0 в качестве целевой платформы из раскрывающегося списка вверху. Оставьте для параметра «Тип аутентификации» значение «Нет» (по умолчанию).
- Убедитесь, что флажки «Включить Docker», «Настроить HTTPS» и «Включить поддержку Open API» сняты, поскольку мы не будем здесь использовать ни одну из этих функций.
- Нажмите Создать.
Мы будем использовать этот проект веб-API ASP.NET Core 6 для работы с EF Core и базой данных в памяти в последующих разделах этой статьи.
Что такое EF Core? Когда нам следует его использовать?
EF Core — это легкий расширяемый ORM (реляционный преобразователь объектов) с открытым исходным кодом, который поддерживает несколько поставщиков баз данных, включая SQLite, MySQL, PostgreSQL и Microsoft SQL Server. (Вы найдете полный список поставщиков EF Core здесь.) И, как мы уже отмечали, EF Core поддерживает хранение и извлечение данных в память и из нее с помощью своего поставщика базы данных в памяти.
EF Core также поддерживает LINQ (Language Integrated Query), что упрощает написание запросов к данным в вашей базе данных. Это связано с тем, что LINQ позволяет писать запросы непосредственно на C# вместо SQL или другого языка запросов.
Возможность хранить и извлекать данные в памяти с помощью поставщика баз данных EF Core In-Memory особенно хорошо подходит для тестирования приложений или создания приложений, которым необходимо временно хранить данные. А поскольку база данных в памяти быстро и быстро настраивается, ее очень удобно использовать для модульного тестирования.
Что такое база данных в памяти?
База данных в памяти — это база данных, которая находится в энергозависимой памяти, а не на физическом диске. Естественно, чтение и запись для базы данных в памяти происходит во много раз быстрее, чем для базы данных на диске, поскольку приложению не нужно ждать физической записи или чтения данных с диска. Чтение и запись данных, хранящихся на физическом диске, — ресурсоемкая операция.
Базы данных в памяти часто используются для целей кэширования, поскольку они могут хранить в памяти копии часто используемых данных для быстрого доступа. Вы также можете воспользоваться базами данных в памяти для хранения временных данных, т. е. данных, которые не нужно сохранять на диске.
Есть также некоторые заметные недостатки использования базы данных в памяти, хотя они относятся к производственному использованию, а не к нашему сценарию тестирования. Одним из них является то, что если вы используете базу данных в памяти, данные не будут сохраняться, когда приложение перестанет работать (если вы не предпримете шаги для их сохранения). Это означает, что в случае сбоя приложения все данные, находящиеся в базе данных в памяти, будут потеряны.
Еще одним недостатком является то, что база данных в памяти использует гораздо больше памяти по сравнению с традиционной базой данных, расположенной на физическом диске (а память намного дороже, чем дисковое хранилище). В результате база данных в памяти может не подойти для приложений, работающих с огромными объемами данных. Но опять же, эти недостатки на самом деле не относятся к использованию базы данных в памяти для тестирования.
Использование базы данных в памяти в ASP.NET Core 6
В этом разделе мы рассмотрим, как можно использовать базу данных в памяти для хранения и извлечения данных в приложении ASP.NET Core 6. Мы выполним следующие шаги, чтобы создать и использовать базу данных в памяти в ASP.NET Core 6:
- Установите пакет NuGet EF Core InMemory.
- Создайте новый пользовательский класс DbContext.
- Создайте классы модели
- Создайте класс репозитория
- Добавьте репозиторий как сервис в контейнер.
- Создать новый контроллер
- Используйте внедрение зависимостей в контроллере для доступа к экземпляру репозитория.
- Выполнить приложение
Давайте начнем!
Установите пакет NuGet EF Core InMemory.
Чтобы использовать возможности EF Core в памяти в вашем приложении, вам следует добавить в проект пакет Microsoft.EntityFrameworkCore.InMemory. Для этого выберите проект в окне обозревателя решений, затем щелкните правой кнопкой мыши и выберите «Управление пакетами NuGet». В окне диспетчера пакетов NuGet найдите пакет Microsoft.EntityFrameworkCore.InMemory и установите его.
Кроме того, вы можете установить пакет через консоль диспетчера пакетов NuGet, введя команду, показанную ниже.
PM> Install-Package Microsoft.EntityFrameworkCore.InMemory
Создайте собственный класс DbContext в ASP.NET Core 6.
В EF Core DbContext используется приложением для взаимодействия с базовой базой данных. Прежде чем продолжить, давайте создадим собственный класс DbContext, который мы будем использовать для расширения класса DbContext платформы EF Core.
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; }
}
}
Обратите внимание, как мы указали имя базы данных в памяти в методе OnConfiguring.
Создание классов моделей в ASP.NET Core 6.
Мы будем использовать два простых класса модели для работы с данными в этом приложении. Этими классами моделей являются Author и Book. Создайте новый файл .cs с именем Author.cs и введите следующий код:
public class Author
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Book> Books { get; set; }
}
Создайте еще один файл .cs с именем Book.cs и введите в него следующий код:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public Author Author { get; set; }
}
Создайте класс репозитория в ASP.NET Core 6.
Создайте интерфейс с именем IAuthorRepository в одноименном файле с расширением .cs и напишите там следующий код:
public interface IAuthorRepository
{
public List<Author> GetAuthors();
}
Класс AuthorRepository реализует члены интерфейса IAuthorRepository, как показано в листинге кода, приведенном ниже.
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;
}
}
}
}
Обратите внимание, как созданный нами ранее пользовательский DbContext используется в классе AuthorRepository для хранения и извлечения данных в базу данных в памяти и из нее.
Добавьте службу репозитория в контейнер служб в ASP.NET Core 6.
Чтобы использовать внедрение зависимостей в ваших контроллерах или других классах вашего проекта, вы должны добавить службы в контейнер внедрения зависимостей.
Добавьте следующую строку кода в файл Program.cs, чтобы добавить службу AuthorRepository в контейнер.
builder.Services.AddScoped<IAuthorRepository, AuthorRepository>();
Вот полный исходный код файла Program.cs для справки:
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();
Создайте контроллер веб-API в ASP.NET Core 6.
Все идет нормально. Теперь щелкните правой кнопкой мыши папку решения «Контроллеры», выберите «Добавить -> Контроллер…» и создайте новый контроллер API в своем проекте. Назовите контроллер AuthorController и замените сгенерированный по умолчанию код следующим:
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());
}
}
}
Обратите внимание, как внедрение зависимостей использовалось для внедрения экземпляра типа IAuthorRepository в конструктор класса AuthorController. Метод действия HttpGet класса AuthorController вызывает метод GetAuthors класса AuthorRepository и возвращает список авторов.
Наконец, когда вы запустите приложение и достигнете конечной точки HttpGet AuthorController с помощью Postman, вы должны увидеть выходные данные, как показано на рисунке 1 ниже.
Рисунок 1. Тестирование нашей простой базы данных в памяти, созданной с помощью ASP.NET Core 6 и EF Core.
Это была минималистичная реализация веб-приложения ASP.NET Core 6, основная цель которой — показать, как работать с базой данных в памяти с помощью EF Core. Вам следует написать собственный код для генерации идентификаторов для обоих классов модели. Кроме того, вы можете воспользоваться модульными тестами для проверки конечных точек вашего приложения. Как и следовало ожидать, модульные тесты, использующие поставщика баз данных EF Core In-Memory, будут выполняться довольно быстро.