На заметку! Важно позаботиться о том, чтобы в сгенерированные файлы или базу данных не вносились изменения до тех пор, пока не будет создана и применена начальная миграция. Изменения на любой из сторон приведут к тому, что код и база данных утратят синхронизацию. После применения начальной миграции все изменения должны вноситься в базу данных через миграции EF Core.
Удостоверьтесь в том, что миграция была создана и ожидает применения, выполнив команду list:
dotnet ef migrations list -c AutoLot.Dal.EfStructures.ApplicationDbContext
Результат покажет, что миграция Initial ожидает обработки (ваша отметка времени будет другой). Строка подключения присутствует в выводе из-за вызова Console.Writeline() в методе CreateDbContext():
Build started...
Build succeeded.
server=.,5433;Database=AutoLot;User Id=sa;Password=P@ssw0rd;
20201231203939_Initial (Pending)
Применение миграции
Самый простой способ применения миграции к базе данных предусматривает ее удаление и повторное создание. Если вас он устраивает, тогда можете ввести приведенные ниже команды и перейти к чтению следующего раздела:
dotnet ef database drop -f
dotnet ef database update Initial -c AutoLot.Dal.EfStructures.ApplicationDbContext
Если вариант с удалением и повторным созданием базы данных не подходит (скажем, в случае базы данных Azure SQL), то инфраструктуре EF Core необходимо обеспечить
dotnet ef migrations script --idempotent -o FirstMigration.sql
Важными частями сценария являются те, которые создают таблицу __EFMigrationsHistory и затем добавляют в нее запись о миграции, указывающую на ее применение. Скопируйте эти части в новый запрос внутри Azure Data Studio или SQL Server Manager Studio. Вот необходимый код SQL (отметка времени у вас будет отличаться):
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
END;
GO
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20201231203939_Initial', N'5.0.1');
Если вы теперь запустите команду list, то она больше не будет отображать миграцию Initial как ожидающую обработки. После применения начальной миграции проект и база данных синхронизированы, а разработка будет продолжаться в стиле "сначала код".
Обновление модели
В этом разделе все текущие сущности обновляются до своих финальных версий, к тому же добавляется сущность регистрации в журнале. Обратите внимание, что ваши проекты не смогут быть скомпилированы вплоть до завершения данного раздела.
Сущности
В каталоге Entities проекта AutoLot.Models вы обнаружите пять файлов, по одному для каждой таблицы в базе данных. Несложно заметить, что имена имеют форму единственного, а не множественного числа (как в базе данных). Это особенность версии EF Core 5, где средство перевода имен в множественное число по умолчанию включено при создании шаблонов сущностей для базы данных.
Изменения, которые вы внесете в сущностные классы, включают добавление базового класса, создание принадлежащего сущностного класса Person, исправление имен навигационных свойств и добавление ряда дополнительных свойств. Кроме того, вы добавите новую сущность для регистрации в журнале (которая будет использоваться в главах, посвященных ASP.NET Core). В предыдущей главе подробно рассматривались соглашения EF Core, аннотации данных и Fluent API, так что в текущей главе будут приводиться в основном листинги кода с краткими описаниями.
Класс BaseEntity
Класс BaseEntity будет содержать столбцы Id и TimeStamp, присутствующие в каждой сущности. Создайте новый каталог по имени Base в каталоге Entities проекта AutoLot.Models. Поместите в этот каталог новый файл BaseEntity.cs со следующим кодом:
using System.ComponentModel.DataAnnotations;