Есть ли способ программно проверить ожидающие изменения модели в Entity Framework Core? - PullRequest
1 голос
/ 14 марта 2020

В настоящее время я занимаюсь настройкой командной среды для ASP. NET Разработка ядра WebAPI с использованием xUnit для модульных тестов в сочетании с GitLab CI. Для связи с базой данных мы используем EF Core.

Для EF Core мы будем использовать Code First Migrations, и мы обеспокоены тем, что разработчик может только обновить модель, а не создавать миграцию для изменения своей модели. Таким образом, мы хотим, чтобы наш CI запускал все миграции, которые существуют в кодовой базе, сравнивал их с текущим состоянием первой модели кода и терпел неудачу, когда состояние первой модели кода не равно состоянию, которое возникает в результате выполнения всех миграций.

Есть ли способ сделать это? Я не могу найти ничего об этом в документации EF Core.

1 Ответ

0 голосов
/ 14 марта 2020

Благодаря примеру кода от @ErikEJ я смог написать следующий тест, который выполняет именно то, что я хочу:

    using FluentAssertions;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Infrastructure;
    using Microsoft.EntityFrameworkCore.Migrations;
    using Xunit;

    /// <summary>
    /// Contains a test that verifies that the
    /// model does not contain any changes that are not included
    /// in the migrations.
    /// </summary>
    public class NoPendingModelChangesTest
    {
        private static readonly string DummyConnectionString = @"Server=localhost;Database=DoesNotExist;Trusted_Connection=True;";

        /// <summary>
        /// Tests that the current model does not contain any changes
        /// that are not contained in the database migrators.
        /// In other words: tests that the current model state equals the
        /// state that results from all the migrations combined.
        /// </summary>
        [Fact]
        public void ModelDoesNotContainPendingChanges()
        {
            // Do not use the test database, the SQL Server model provider must be
            // used as that is the model provider that is used for scaffolding migrations.
            using var ctx = new MyDatabase(
                new DbContextOptionsBuilder<MyDatabase>()
                    .UseSqlServer(DummyConnectionString)
                    .Options);

            var modelDiffer = ctx.GetService<IMigrationsModelDiffer>();
            var migrationsAssembly = ctx.GetService<IMigrationsAssembly>();

            var pendingModelChanges = modelDiffer
                .GetDifferences(
                    migrationsAssembly.ModelSnapshot?.Model,
                    ctx.Model);

            pendingModelChanges
                .Should()
                .BeEmpty(
                    because:
                        "the current model state should be equal to the state that results from all the migrations combined (try scaffolding a migration)");
        }
    }
...