Чтобы ответить на ваш вопрос «Имя пользователя и пароль пользователя (включая пользователя с правами администратора) жестко закодированы в методе Seed, это приемлемая практика?»
Нет, вы должны хранить свой пароль в формате открытого текста, хотя выможете сохранить его в режиме шифрования и заполнить его.
В EF Core 2.1 рабочий процесс заполнения совершенно другой.Теперь есть логика Fluent API для определения начальных данных в OnModelCreating
.Затем, когда вы создаете миграцию, начальное преобразование преобразуется в команды миграции для выполнения вставок и в конечном итоге преобразуется в SQL, который выполняет конкретная миграция.Дальнейшие миграции будут знать, чтобы вставить больше данных или даже выполнить обновления и удаления, в зависимости от того, какие изменения вы вносите в метод OnModelCreating
.
Предположим, что три класса в моей модели - это Журнал, Статья и Автор.Журнал может иметь одну или несколько статей, а статья может иметь одного автора.Есть также PublicationsContext
, который использует SQLite в качестве своего поставщика данных и имеет некоторые базовые настройки ведения журналов SQL.
Давайте рассмотрим пример с одним типом сущности.
Давайте начнем с того, как он выглядитхотел бы предоставить начальные данные для журнала - в самом простом виде.
Ключом к новой функции заполнения является метод HasData Fluent API, который можно применить к сущности в методе OnModelCreating.
Вот структура типа Журнал:
public class Magazine
{
public int MagazineId { get; set; }
public string Name { get; set; }
public string Publisher { get; set; }
public List<Article> Articles { get; set; }
}
Он имеет ключевое свойство MagazineId, две строки и список типов Статьи.Теперь давайте заполним их данными для одного журнала:
protected override void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity<Magazine> ().HasData
(new Magazine { MagazineId = 1, Name = "MSDN Magazine" });
}
Несколько вещей, на которые следует обратить внимание: во-первых, я явно устанавливаю ключевое свойство MagazineId.Во-вторых, я не предоставляю строку Publisher.
Далее я добавлю миграцию, мою первую модель для этой модели.Я использую код Visual Studio для этого проекта, который является приложением .NET Core, поэтому я использую команду миграции интерфейса командной строки «dotnet ef migrations add init». Полученный файл миграции содержит все обычные CreateTable и другие.соответствующая логика, за которой следует код для вставки новых данных с указанием имени таблицы, столбцов и значений:
migrationBuilder.InsertData(
table: "Magazines",
columns: new[] { "MagazineId", "Name", "Publisher" },
values: new object[] { 1, "MSDN Magazine", null });
Вставка значения первичного ключа выделяется здесь, особенно после того, как я проверил, как MagazineIdстолбец был определен далее в файле миграции.Это столбец, который должен автоматически увеличиваться, поэтому вы не можете ожидать, что это значение будет вставлено явно:
MagazineId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true)
Давайте продолжим, чтобы увидеть, как это работает.Используя команду сценария миграции «dotnet ef migrations script», чтобы показать, что будет отправлено в базу данных, я вижу, что значение первичного ключа все еще будет вставлено в столбец ключа:
INSERT INTO "Magazines" ("MagazineId", "Name", "Publisher")
VALUES (1, 'MSDN Magazine', NULL);
Этопотому что я нацелился на SQLite.SQLite вставит значение ключа, если оно предоставлено, переопределяя автоинкремент.Но как насчет базы данных SQL Server, которая определенно не будет делать это на лету?
Я переключил контекст на использование поставщика SQL Server для исследования и увидел, что SQL, созданный поставщиком SQL Server, включает в себялогика для временного включения IDENTITY_INSERT ON.Таким образом, предоставленное значение будет вставлено в столбец первичного ключа.Загадка разгадана!
Вы можете использовать HasData для вставки нескольких строк одновременно, хотя имейте в виду, что HasData относится только к одной сущности.Вы не можете объединить вставки в несколько таблиц с HasData.Здесь я вставляю два журнала одновременно:
modelBuilder.Entity<Magazine>()
.HasData(new Magazine{MagazineId=2, Name="New Yorker"},
new Magazine{MagazineId=3, Name="Scientific American"}
);
Для полного примера вы можете просмотреть этот образец репо
Надеюсь, это поможет.