Мы все были там: создать новый проект для клиента, создать базу данных в той или иной форме, поделиться проектом и включить некоторые инструкции о том, как создать базу данных для проекта.

Они получают проект, он строится — и это здорово! — но затем дело доходит до построения базы данных. У них может не быть экземпляра используемой вами системы баз данных (MSSQL, MYSQL, MongoDB и т. д.), что означает, что они не смогут запустить проект.

К счастью для нас и для них, это не конец света; есть способы обойти эту проблему.

Давайте воспользуемся функцией EntityFramework InMemory. Я создал проект Razor Page .NET 5 и установил следующие пакеты NuGet:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.InMemory

После их установки мы можем создать очень простую структуру базы данных. Давайте сначала создадим две таблицы, которые мы хотим сохранить:

База данных/таблицы/Movie.cs

namespace EFInMemoryDatabase.Database.Tables
{
    public class Movie
    {
        public int MovieId { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public int GenreId { get; set; }
    }
}

Database/Tables/Genre.cs (это не используется, просто для демонстрации)

namespace EFInMemoryDatabase.Database.Tables
{
    public class Genre
    {
        public int GenreId { get; set; }
        public string Label { get; set; }
    }
}

Теперь нам нужно создать настоящую базу данных. Мы создадим два набора DbSet, один для фильма и один для жанра. Класс DbSet представляет набор сущностей, который можно использовать для операций с базой данных, таких как создание, чтение, обновление и удаление (https://entityframework.net/ef-dbset).

База данных/MovieContext.cs

using EFInMemoryDatabase.Database.Tables;
using Microsoft.EntityFrameworkCore;
namespace EFInMemoryDatabase.Database
{
    public class MovieContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
        public DbSet<Genre> Genres { get; set; }
        public MovieContext(DbContextOptions options) : base(options)  
        {
            LoadMovies();
            LoadGenres();
            SaveChanges();
        }
        public void LoadMovies()
        {
            Movies.Add(new Movie()
            {
                Description = "An organized crime dynasty's aging patriarch transfers control of his clandestine empire to his reluctant son.",
                GenreId = 1,
                MovieId = 1,
                Title = "The Godfather"
            });
            Movies.Add(new Movie()
            {
                Description = "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.",
                GenreId = 2,
                MovieId = 2,
                Title = "The Shawshank Redemption"
            });
            Movies.Add(new Movie()
            {
                Description = "In German-occupied Poland during World War II, industrialist Oskar Schindler gradually becomes concerned for his Jewish workforce after witnessing their persecution by the Nazis.",
                GenreId = 2,
                MovieId = 3,
                Title = "Schindler's List "
            });
        }
        public void LoadGenres()
        {
            Genres.Add(new Genre()
            {
                GenreId = 1,
                Label = "Crime"
            });
            Genres.Add(new Genre()
            {
                GenreId = 2,
                Label = "Drama"
            });
        }
    }
}

Теперь давайте обновим наш Startup.cs, чтобы мы могли настроить DI (внедрение зависимостей) для нашего приложения. В нашем Startup.cs нам нужно будет добавить контекст базы данных и использовать функцию «UseInMemoryDatabase», которая поставляется из пакета Microsoft.EntityFrameworkCore.InMemory NuGet.

Startup.cs

...
public void ConfigureServices(IServiceCollection services)
{
    // Add this single line into your ConfigureServices method
    services.AddDbContext<MovieContext>(o => o.UseInMemoryDatabase(nameof(MovieContext)));
    services.AddRazorPages();
}
...

Теперь давайте обновим наш код Index.cshtml, чтобы мы могли собирать наши фильмы из базы данных, а затем отображать их на странице.

Страницы/Index.cshtml

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}
<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
@foreach (var x in Model.Movies)
    {
        <h1>@x.Title</h1>
        <span>@x.Description</span>
        <i>Genre: @x.GenreId</i>
    }
</div>

Страницы/Index.cshtml.cs

using EFInMemoryDatabase.Database;
using EFInMemoryDatabase.Database.Tables;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
namespace EFInMemoryDatabase.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        private readonly MovieContext _context;
        public List<Movie> Movies { get; set; }
        public IndexModel(
            ILogger<IndexModel> logger,
            MovieContext context)
        {
            _logger = logger;
            _context = context;
        }
        public void OnGet()
        {
            Movies = _context.Movies.ToList();
        }
    }
}

И это все! Теперь любой, кому вы дадите этот проект, сможет запустить его без проблем.

База данных заполняется автоматически при построении и хранится в памяти. Это означает, что любые изменения, которые вы делаете в веб-приложении I.E. добавление нового фильма будет потеряно при остановке приложения (функция добавления фильма в базу данных не реализована). Но помните, что функция InMemory предназначена для тестирования/прототипирования.

Если вы просто хотите увидеть код в действии, вы можете скачать мой код с GitHub здесь (вам потребуется установленный .NET 5 SDK): https://github.com/MrApproved/Medium_EFInMemoryDatabase

Спасибо за прочтение, надеюсь, это помогло вам или научило вас чему-то новому. Не стесняйтесь оставлять отзывы, положительные или отрицательные.

Ссылки:
https://www.entityframeworktutorial.net/what-is-entityframework.aspx
https://entityframeworkcore.com/providers-inmemory

Репозиторий: https://github.com/MrApproved/Medium_EFInMemoryDatabase
Изображение: https://www.pexels.com/photo/green-typewriter-with-white-typewriter-4065406/