Упражнение. Настройка миграции
В этом уроке вы создадите классы сущностей C#, которые сопоставляют таблицы в локальной базе данных SQLite. Функция миграции EF Core создает таблицы из этих сущностей.
Миграция позволяет постепенно обновлять схему базы данных.
Получение файлов проекта
Чтобы приступить к работе, получите файлы проекта. У вас есть несколько вариантов получения файлов проекта:
- Использование GitHub Codespaces
- Клонирование репозитория GitHub
Если установлена совместимая среда выполнения контейнера, можно также использовать расширение "Контейнеры разработки" для открытия репозитория в контейнере с предварительно установленными средствами.
Использование GitHub Codespaces
Пространство кода — это интегрированная среда разработки, размещенная в облаке. Если вы используете GitHub Codespaces, перейдите в репозиторий в браузере. Выберите код и создайте новое пространство кода в main
ветви.
Клонирование репозитория GitHub
Если вы не используете GitHub Codespaces, вы можете клонировать репозиторий проекта GitHub, а затем открыть файлы в виде папки в Visual Studio Code.
Откройте командный терминал и клонируйте проект из GitHub с помощью командной строки:
git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
Перейдите в папку mslearn-persist-data-ef-core , а затем откройте проект в Visual Studio Code:
cd mslearn-persist-data-ef-core code .
Просмотр кода
Теперь, когда у вас есть файлы проекта для работы, давайте посмотрим, что находится в проекте и просмотрите код.
- Проект веб-API ASP.NET Core расположен в каталоге ContosoPizza . Пути к файлам, которые мы ссылаемся в этом модуле, относятся к каталогу ContosoPizza .
- Services/PizzaService.cs — это класс службы, определяющий методы создания, чтения, обновления и удаления (CRUD). Все методы сейчас выдают исключение
System.NotImplementedException
. - В Program.cs
PizzaService
регистрируется в системе внедрения зависимостей ASP.NET Core. - Контроллеры/PizzaController.cs — это значение,
ApiController
которое предоставляет конечную точку для команд HTTP POST, GET, PUT и DELETE. Эти команды вызывают соответствующие методы CRUD вPizzaService
.PizzaService
внедряется вPizzaController
конструктор. - Папка Models содержит модели, которые
PizzaService
иPizzaController
используются. - Модели сущностей, Pizza.cs, Topping.cs и Sauce.cs имеют следующие связи:
- Пицца может иметь одну или несколько начинок.
- Начинку можно использовать на одном или на многих пиццах.
- Пицца может иметь один соус, но соус может быть использован на многих пиццах.
Создание приложения
Чтобы создать приложение в Visual Studio Code, выполните следующие действия.
В области обозревателя щелкните правой кнопкой мыши каталог ContosoPizza и выберите "Открыть в интегрированном терминале".
Откроется область терминала, которая находится в каталоге ContosoPizza .
Создайте приложение с помощью следующей команды:
dotnet build
Компиляция кода должна пройти успешно без предупреждений или ошибок.
Добавление пакетов NuGet и инструментов EF Core
Ядро СУБД, с которым вы работаете в этом модуле, — SQLite. SQLite — это упрощенный ядро СУБД на основе файлов. Это хороший выбор для разработки и тестирования, и это также хороший выбор для небольших рабочих развертываний.
Примечание.
Как упоминалось ранее, поставщики баз данных в EF Core подключаются. SQLite — это хороший выбор для этого модуля, так как он является упрощенным и кроссплатформенным. Вы можете использовать один и тот же код для работы с различными ядрами СУБД, такими как SQL Server и PostgreSQL. В одном приложении можно даже использовать несколько ядр субД.
Перед началом добавьте необходимые пакеты:
В области терминала выполните следующую команду:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
Эта команда добавляет пакет NuGet с поставщиком базы данных SQLite Entity Framework Core и всеми его зависимостями, в том числе с общими службами Entity Framework Core.
Затем выполните следующую команду:
dotnet add package Microsoft.EntityFrameworkCore.Design
Эта команда добавляет пакеты, необходимые для средств EF Core.
Чтобы завершить работу, выполните следующую команду:
dotnet tool install --global dotnet-ef
Эта команда устанавливает
dotnet ef
средство, используемое для создания миграций и шаблонов.Совет
Если
dotnet ef
он уже установлен, его можно обновить, выполнив командуdotnet tool update --global dotnet-ef
.
Модели шаблонов и DbContext
Теперь вы добавляете и настраиваете реализацию DbContext
. DbContext
— это шлюз, с помощью которого можно взаимодействовать с базой данных.
Щелкните правой кнопкой мыши каталог ContosoPizza и добавьте новую папку с именем Data.
В папке "Данные" создайте файл с именем PizzaContext.cs. Добавьте следующий код в пустой файл:
using Microsoft.EntityFrameworkCore; using ContosoPizza.Models; namespace ContosoPizza.Data; public class PizzaContext : DbContext { public PizzaContext (DbContextOptions<PizzaContext> options) : base(options) { } public DbSet<Pizza> Pizzas => Set<Pizza>(); public DbSet<Topping> Toppings => Set<Topping>(); public DbSet<Sauce> Sauces => Set<Sauce>(); }
В предыдущем коде:
- Конструктор принимает параметр с типом
DbContextOptions<PizzaContext>
. Конструктор позволяет внешнему коду передавать конфигурацию, чтобы ониDbContext
могли совместно использоваться между тестом и рабочим кодом, а также использовать их с различными поставщиками. - Свойства
DbSet<T>
соответствуют таблицам для создания в базе данных. - Имена таблиц соответствуют именам
DbSet<T>
свойств вPizzaContext
классе. Это поведение можно переопределить при необходимости. - При создании
PizzaContext
экземпляра предоставляет свойстваPizzas
Toppings
иSauces
свойства. Изменения, внесенные в коллекции, предоставляемые этими свойствами, распространяются в базу данных.
- Конструктор принимает параметр с типом
В Program.cs замените
// Add the PizzaContext
следующим кодом:builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");
Предыдущий код:
- Регистрируется
PizzaContext
в системе внедрения зависимостей ASP.NET Core. - Указывает, что
PizzaContext
использует поставщик базы данных SQLite. - Определяет строку подключения SQLite, которая указывает на локальный файл ContosoPizza.db.
Примечание.
SQLite использует локальные файлы базы данных, поэтому это нормально для жесткого кода строка подключения. Для сетевых баз данных, таких как PostgreSQL и SQL Server, всегда следует безопасно хранить строка подключения. Для разработки в локальной среде используйте диспетчер секретов. Для рабочих развертываний рекомендуется использовать службу, например Azure Key Vault.
- Регистрируется
В файле Program.cs также замените
// Additional using declarations
приведенным ниже кодом.using ContosoPizza.Data;
Этот код разрешает зависимости на предыдущем шаге.
Сохраните изменения. GitHub Codespaces автоматически сохраняет изменения.
Выполните сборку приложения в терминале
dotnet build
. Сборка должна завершиться успешно без предупреждений или ошибок.
Создание и выполнение миграции
Затем создайте миграцию, которую можно использовать для создания исходной базы данных.
В терминале в папке проекта ContosoPizza выполните следующую команду, чтобы создать миграцию для создания таблиц базы данных:
dotnet ef migrations add InitialCreate --context PizzaContext
В предыдущей команде используются следующие параметры:
- Миграция называется: InitialCreate.
- Параметр
--context
задает имя класса в проекте ContosoPizza, который является производным отDbContext
.
Новый каталог Migrations отображается в корне проекта ContosoPizza. Каталог содержит <timestamp>_InitialCreate.cs файл, описывающий изменения базы данных, которые будут преобразованы в скрипт изменений языка определения данных (DDL).
Выполните следующую команду, чтобы применить миграцию InitialCreate:
dotnet ef database update --context PizzaContext
Эта команда применяет миграцию. ContosoPizza.db не существует, поэтому эта команда создает миграцию в каталоге проекта.
Совет
Все платформы поддерживают
dotnet ef
средство. В Visual Studio в Windows можно использоватьAdd-Migration
Update-Database
командлеты PowerShell в интегрированном окне консоли диспетчер пакетов.
Проверка базы данных
В EF Core создана база данных для вашего приложения. Далее давайте рассмотрим базу данных с помощью расширения SQLite.
В области обозревателя щелкните правой кнопкой мыши файл ContosoPizza.db и выберите "Открыть базу данных".
Папка SQLite Explorer отображается в области обозревателя .
Выберите папку SQLite Explorer , чтобы развернуть узел и все дочерние узлы. Щелкните правой кнопкой мыши ContosoPizza.db и выберите "Показать таблицу sqlite_master", чтобы просмотреть всю схему базы данных и ограничения, созданные миграцией.
- Были созданы таблицы, соответствующие каждой сущности.
- Таблицы именованы согласно именам свойств
DbSet
вPizzaContext
. - Свойства, именованные
Id
, были выведены для автоматического увеличения полей первичного ключа. - Первичный ключ EF Core и соглашения об именовании внешних ключей имеют
PK_<primary key property>
иFK_<dependent entity>_<principal entity>_<foreign key property>
соответственно. Заполнители<dependent entity>
и<principal entity>
соответствуют именам классов сущностей.
Примечание.
Как и ASP.NET Core MVC, EF Core использует соглашение о подходе к конфигурации . Соглашения EF Core сокращают время разработки путем определения намерения разработчика. Например, EF Core определяет свойство с именем
Id
или<entity name>Id
первичным ключом созданной таблицы. Если вы решили не принимать соглашение об именовании, необходимо нажать на свойство атрибутом[Key]
или настроить его в качестве ключа вOnModelCreating
методеDbContext
.
Изменение модели и обновление схемы базы данных
Ваш менеджер в Contoso Pizza предоставляет вам некоторые новые требования, поэтому вам нужно изменить модели сущностей. В следующих шагах вы изменяете модели с помощью атрибутов сопоставления (иногда называемых заметками данных).
В файле Models\Pizza.cs внесите следующие изменения:
- Добавьте директиву
using
дляSystem.ComponentModel.DataAnnotations
. - Добавьте атрибут
[Required]
перед свойствомName
, чтобы пометить свойство как обязательное. - Добавьте атрибут
[MaxLength(100)]
перед свойствомName
, чтобы задать максимальную длину строк в 100 символов.
Обновленный файл Pizza.cs должен выглядеть следующим образом:
using System.ComponentModel.DataAnnotations; namespace ContosoPizza.Models; public class Pizza { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public Sauce? Sauce { get; set; } public ICollection<Topping>? Toppings { get; set; } }
- Добавьте директиву
В файле Models\Sauce.cs внесите следующие изменения:
- Добавьте директиву
using
дляSystem.ComponentModel.DataAnnotations
. - Добавьте атрибут
[Required]
перед свойствомName
, чтобы пометить свойство как обязательное. - Добавьте атрибут
[MaxLength(100)]
перед свойствомName
, чтобы задать максимальную длину строк в 100 символов. - Добавьте свойство типа
bool
с именемIsVegan
.
Обновленный файл Sauce.cs должен выглядеть следующим образом:
using System.ComponentModel.DataAnnotations; namespace ContosoPizza.Models; public class Sauce { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public bool IsVegan { get; set; } }
- Добавьте директиву
В файле Models\Topping.cs внесите следующие изменения:
Добавьте директивы
using
дляSystem.ComponentModel.DataAnnotations
иSystem.Text.Json.Serialization
.Добавьте атрибут
[Required]
перед свойствомName
, чтобы пометить свойство как обязательное.Добавьте атрибут
[MaxLength(100)]
перед свойствомName
, чтобы задать максимальную длину строк в 100 символов.Сразу после свойства
Name
добавьте свойство типаdecimal
с именемCalories
.Pizzas
Добавьте свойство типаICollection<Pizza>?
. Это изменение делаетPizza
-Topping
связь "многие ко многим".Добавьте атрибут
[JsonIgnore]
к свойствуPizzas
.Внимание
Этот атрибут запрещает
Topping
сущностям включатьPizzas
свойство, когда код веб-API сериализует ответ на JSON. Без этого изменения сериализованная коллекция начинок будет включать коллекцию каждой пиццы, которая использует начинку. Каждая пицца в этой коллекции будет содержать коллекцию начинок, которые, опять-таки, будут содержать коллекцию объектов пиццы. Бесконечный цикл такого типа называется циклической ссылкой, и его нельзя сериализовать.
Обновленный файл Topping.cs должен выглядеть следующим образом:
using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace ContosoPizza.Models; public class Topping { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public decimal Calories { get; set; } [JsonIgnore] public ICollection<Pizza>? Pizzas { get; set; } }
Сохраните все изменения и запустите
dotnet build
.Выполните следующую команду, чтобы создать миграцию для создания таблиц базы данных:
dotnet ef migrations add ModelRevisions --context PizzaContext
Эта команда создает миграцию с именем: ModelRevisions
Примечание.
Вы увидите это сообщение: операция была шаблонирована, которая может привести к потере данных. Просмотрите миграцию для точности. Это сообщение появилось, так как вы изменили связь с
Pizza
Topping
"один ко многим" на "многие", что требует удаления существующего столбца внешнего ключа. Так как у вас еще нет данных в базе данных, это изменение не проблематично. Однако в целом рекомендуется проверить созданную миграцию при появлении этого предупреждения, чтобы убедиться, что миграция не удаляет или усечена никакие данные.Выполните следующую команду, чтобы применить миграцию ModelRevisions:
dotnet ef database update --context PizzaContext
В строке заголовка папки SQLite Explorer нажмите кнопку "Обновить базы данных ".
В папке SQLite Explorer щелкните правой кнопкой мыши ContosoPizza.db. Выберите пункт Отобразить таблицу sqlite_master, чтобы просмотреть полную схему базы данных и ограничения.
Внимание
Расширение SQLite повторно использует открытые вкладки SQLite .
- Таблица
PizzaTopping
соединения была создана для представления отношений "многие ко многим" между пиццами и начинками. - Добавлены и
Sauces
добавленыToppings
новые поля.Calories
определен как столбец типаtext
, так как в SQLite нет соответствующего типаdecimal
.- Аналогичным образом
IsVegan
определен как столбец с типомinteger
. SQLite не определяет типbool
. - В обоих случаях преобразованием управляет EF Core.
- Столбец
Name
в каждойMaxLength
таблице помеченnot null
, но SQLite не имеет ограничения.
Совет
Поставщики баз данных EF Core сопоставляют схему модели с функциями конкретной базы данных. Хотя SQLite не реализует соответствующее ограничение для
MaxLength
других баз данных, таких как SQL Server и PostgreSQL.- Таблица
В папке SQLite Explorer щелкните таблицу правой
_EFMigrationsHistory
кнопкой мыши и выберите " Показать таблицу". Таблица содержит список всех миграций, применяемых к базе данных. Так как вы выполнили две миграции, есть две записи: одна для миграции InitialCreate и другая для ModelRevisions.
Примечание.
Это упражнение использовало атрибуты сопоставления (заметки данных) для сопоставления моделей с базой данных. В качестве альтернативы сопоставлению атрибутов можно использовать API fluent ModelBuilder для настройки моделей. Оба подхода являются допустимыми, но некоторые разработчики предпочитают один подход по сравнению с другим.
Вы использовали миграции для определения и обновления схемы базы данных. В следующем уроке вы выполните методы в PizzaService
, которые управляют данными.