Шрифт:
Интервал:
Закладка:
Если инструменту не удалось его найти, то экземпляр класса, производного от DbContext, будет создаваться с использованием конструктора без параметров. Если ни того и ни другого не существует, тогда команда потерпит неудачу. Обратите внимание, что вариант с конструктором без параметров требует наличия переопределенной версии OnConfiguring(), что не считается хорошей практикой.
Лучший (и на самом деле единственный) вариант — всегда создавать реализацию IDesignTimeDbContextFactory<TContext> для каждого класса, производного от DbContext, который присутствует в приложении.
Чтобы вывести список всех аргументов и параметров для команды, введите dotnet ef <команда> -h в окне командной строки, например:
dotnet ef migrations add -h
На заметку! Важно отметить, что команды CLI — это не команды С#, а потому правила отмены символов обратной косой черты и кавычек здесь не применяются.
Команды для управления миграциями
Команды migrations используются для добавления, удаления, перечисления и создания сценариев миграций. После того, как миграция применена к базе данных, в таблице __EFMigrationsHistory создается запись. Команды для управления миграциями кратко описаны в табл. 22.11 и более подробно в последующих подразделах.
Команда add
Команда add создает новую миграцию базы данных, основываясь на текущей объектной модели. Процесс исследует каждую сущность со свойством DbSet<T> в производном от DbContext классе (и каждую сущность, которая может быть достигнута из таких сущностей с использованием навигационных свойств) и выясняет, есть ли какие-то изменения, которые должны быть применены к базе данных. При наличии изменений генерируется надлежащий код для обновления базы данных. Вскоре вы узнаете об этом больше.
Команда add требует передачи параметра name, который используется при именовании созданного класса и файлов для миграции. В дополнение к общим параметрам параметр -о <путь> или --output-dir <путь> указывает, куда должны помещаться файлы миграции. Стандартный каталог называется Migrations и относителен к текущему пути.
Для каждой добавленной миграции создаются два файла с частичными определениями того же самого класса. Имена обоих файлов начинаются с отметки времени и наименования миграции, которое было указано в качестве параметра для команды add. Первый файл называется <ГГГГММДДЧЧММСС>_<НаименованиеМиграции>.cs, а второй — <ГГГГММДДЧЧММСС>_<НаименованиеМиграции>.Designer.cs. Отметка времени основана на том, когда файл был создан, и в точности совпадает для обоих файлов. Первый файл представляет код, сгенерированный для изменений базы данных в этой миграции, а конструирующий файл — код, который предназначен для создания и обновления базы данных на основе всех миграций до этой миграции включительно.
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})Главный файл содержит два метода, Up() и Down(). В методе Up() находится код для обновления базы данных с учетом изменений этой миграции. В методе Down() содержится код для выполнения отката изменений этой миграции. Ниже приведен неполный листинг начальной миграции, рассматриваемой ранее в главе (One2Many):
public partial class One2Many : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Make",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
TimeStamp = table.Column<byte[]>(type: "varbinary(max)",
nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Make", x => x.Id);
});
...
migrationBuilder.CreateIndex(
name: "IX_Cars_MakeId",
table: "Cars",
column: "MakeId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "Cars");
migrationBuilder.DropTable(name: "Make");
}
}
Как видите, метод Up() создает таблицы, столбцы, индексы и т.д. Метод Down() удаляет созданные элементы. По мере необходимости механизм миграции будет выдавать операторы alter, add и drop, чтобы гарантировать соответствие базы данных вашей модели.
Конструирующий файл содержит два атрибута, которые связывают частичные определения с именем файла и классом, производным от DbContext. Ниже показан фрагмент листинга конструирующего класса с упомянутыми атрибутами:
- Понимание SQL - Мартин Грубер - Базы данных