Работа с основными ограничениями SQLite EF - Основные операции - PullRequest
0 голосов
/ 15 июня 2019

Согласно документации некоторые базовые операции для разработки баз данных с использованием миграций не поддерживаются EF Core SQLite (например, удаление столбцов, установка внешних ключей и т. Д.). Итак, как выполнить простые изменения структуры базы данных, такие как удаление столбца без потери данных и синхронизация модели моментального снимка с базой данных (без эшафот)?

Стоит ли это усилий или я должен просто зайти в базу данных и использовать scaffold-command-updates для модели? Если я не могу выполнить все необходимые операции в процессе миграции для обновления своей базы данных, поэтому я не могу использовать преимущества миграции для восстановления структуры моей базы данных. Так в чем же преимущество использования миграций в EF-Core-Sqlite? ORM должны снять работу и не усложнять работу.

1 Ответ

2 голосов
/ 15 июня 2019

как выполнить простые изменения структуры базы данных, такие как удаление столбца без потери данных и синхронизация модели снимка с базой данных (без каркаса)?

Основная идея описана в базовой документации EF: обходной путь ограничения миграции

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

Например, мы создали базу данных со следующей Blog таблицей

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Foo { get; set; }
}

... тогда мы хотим удалить Foo.

Для этого удалите свойство класса Blog.Foo, показанное выше.
Затем добавьте миграцию, чтобы создать класс Migration.
Поскольку MigrationBuilder.DropColumn не поддерживается в SQLite, мы должны изменить метод миграции Up, как описано в документации.

protected override void Up(MigrationBuilder migrationBuilder)
{
    // Create temporary Blog table with new schema
    migrationBuilder.CreateTable(
        name: "Blog_temp_new",
        columns: table => new
        {
            BlogId = table.Column<int>(nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            Name = table.Column<string>(nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Blog", x => x.BlogId);
        });

    // Copy Blog to Blog_temp_new
    migrationBuilder.Sql("INSERT INTO Blog_temp_new (BlogId, Name) SELECT BlogId, Name FROM Blog;");

    // Delete Blog
    migrationBuilder.DropTable("Blog");

    // Rename Blog_temp_new to Blog
    migrationBuilder.RenameTable("Blog_temp_new", newName: "Blog");
}

Все данные Blog с их BlogId и Name будут сохранены при вызове Database.Migrate.

Я предлагаю вам попробовать это в новом проекте с простым единственным классом, как пример Blog. Есть и другие вещи, которые вам нужно сделать, если ваша таблица имеет ограничения или индексы. Но вы сможете легко научиться справляться с ними, если будете экспериментировать в простой песочнице, а не пытаться исправить это в своем основном проекте.

Стоит ли усилий

Исходя из моего опыта, да! Я считаю, что с Model-First легче работать, чем с Database-First. Я предпочитаю делать все в C #, насколько это возможно, но если вы являетесь экспертом по SQL, то, возможно, у вас будет другое мнение, чем у меня. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...