public ConcreteRelationalDatabase(
     DbContext context,
     IRelationalDataStoreCreator dataStoreCreator,
     IRelationalConnection connection,
     IMigrator migrator,
     ILoggerFactory loggerFactory)
     : base(context, dataStoreCreator, connection, migrator, loggerFactory)
 {
 }
示例#2
0
 public static Task MigrateAsync(this DbContext v, string migration = "")
 {
     if (string.IsNullOrEmpty(migration))
     {
         return(v.Database.MigrateAsync());
     }
     else
     {
         IMigrator migrator = v.GetInfrastructure().GetService <IMigrator>();
         return(migrator.MigrateAsync(migration));
     }
 }
示例#3
0
        public static void Initialize(TestContext context)
        {
            var sourceMock = new Mock <ISourceConnector>();

            sourceMock.Setup(m => m.GetOrder(It.IsAny <int>()))
            .Returns(Task.FromResult(MocksProvider.GetEmptyOrderDtoMock()));
            var targetMock = new Mock <ITargetConnector>();

            targetMock.Setup(m => m.SubmitOrder(It.IsAny <OrderDto>()))
            .Returns(Task.FromResult(true));
            migrator = new MigratorService(sourceMock.Object, targetMock.Object);
        }
示例#4
0
 public static void Migrate(this DbContext v, string migration = "")
 {
     if (string.IsNullOrEmpty(migration))
     {
         v.Database.Migrate();
     }
     else
     {
         IMigrator migrator = v.GetInfrastructure().GetService <IMigrator>();
         migrator.Migrate(migration);
     }
 }
 /// <summary>
 ///     Clones this dependency parameter object with one service replaced.
 /// </summary>
 /// <param name="migrator"> A replacement for the current dependency of this type. </param>
 /// <returns> A new parameter object with the given service replaced. </returns>
 public MigrationsScaffolderDependencies With([NotNull] IMigrator migrator)
 => new MigrationsScaffolderDependencies(
     CurrentContext,
     Model,
     MigrationsAssembly,
     MigrationsModelDiffer,
     MigrationsIdGenerator,
     MigrationsCodeGeneratorSelector,
     HistoryRepository,
     OperationReporter,
     DatabaseProvider,
     SnapshotModelProcessor,
     migrator);
示例#6
0
        public void AddMigrator(XmlNode configNode)
        {
            IMigrator migrator = Factory.CreateObject(configNode, false) as IMigrator;

            if (migrator != null)
            {
                this.Migrators.Add(migrator);
            }
            else
            {
                LogHelper.Warn("Migrator could not be resolved", this);
            }
        }
示例#7
0
        public IntegrationTestDbFixture()
        {
            ClassFactory = Bootstrapper.Init("TenderSearch*.dll");

            dbMigration = ClassFactory.GetMigrator(Environments.PRODUCTION);

            if (dbMigration == null)
            {
                throw new NoNullAllowedException("dbMigration not found..");
            }

            dbMigration.Execute(DB_DIRECTORY);
        }
 /// <summary>
 ///     Constructs the event payload.
 /// </summary>
 /// <param name="eventDefinition"> The event definition. </param>
 /// <param name="messageGenerator"> A delegate that generates a log message for this event. </param>
 /// <param name="migrator">
 ///     The <see cref="IMigrator" /> in use.
 /// </param>
 /// <param name="migration">
 ///     The <see cref="Migration" /> being processed.
 /// </param>
 /// <param name="fromMigration">
 ///     The migration that scripting is starting from.
 /// </param>
 /// <param name="toMigration">
 ///     The migration that scripting is going to.
 /// </param>
 /// <param name="idempotent">
 ///     Indicates whether or not the script is idempotent.
 /// </param>
 public MigrationScriptingEventData(
     [NotNull] EventDefinitionBase eventDefinition,
     [NotNull] Func <EventDefinitionBase, EventData, string> messageGenerator,
     [NotNull] IMigrator migrator,
     [NotNull] Migration migration,
     [CanBeNull] string fromMigration,
     [CanBeNull] string toMigration,
     bool idempotent)
     : base(eventDefinition, messageGenerator, migrator, migration)
 {
     FromMigration = fromMigration;
     ToMigration   = toMigration;
     IsIdempotent  = idempotent;
 }
 /// <summary>
 ///     Constructs the event payload.
 /// </summary>
 /// <param name="eventDefinition">The event definition.</param>
 /// <param name="messageGenerator">A delegate that generates a log message for this event.</param>
 /// <param name="migrator">
 ///     The <see cref="IMigrator" /> in use.
 /// </param>
 /// <param name="migration">
 ///     The <see cref="Migration" /> being processed.
 /// </param>
 /// <param name="fromMigration">
 ///     The migration that scripting is starting from.
 /// </param>
 /// <param name="toMigration">
 ///     The migration that scripting is going to.
 /// </param>
 /// <param name="idempotent">
 ///     Indicates whether or not the script is idempotent.
 /// </param>
 public MigrationScriptingEventData(
     EventDefinitionBase eventDefinition,
     Func <EventDefinitionBase, EventData, string> messageGenerator,
     IMigrator migrator,
     Migration migration,
     string?fromMigration,
     string?toMigration,
     bool idempotent)
     : base(eventDefinition, messageGenerator, migrator, migration)
 {
     FromMigration = fromMigration;
     ToMigration   = toMigration;
     IsIdempotent  = idempotent;
 }
示例#10
0
        public static void MigrateDatabase <T>(this IWebHost host, string migration = "") where T : DbContext
        {
            using IServiceScope scope = host.Services.CreateScope();
            T db = scope.ServiceProvider.GetRequiredService <T>();

            if (string.IsNullOrEmpty(migration))
            {
                db.Database.Migrate();
            }
            else
            {
                IMigrator migrator = db.GetInfrastructure().GetService <IMigrator>();
                migrator.Migrate(migration);
            }
        }
示例#11
0
        public MigrationRunner(ILogger log, IMigrator migrator, IMigrationRunnerSettings settings, IExternalConfiguration externalConfiguration)
        {
            ExternalConfiguration = externalConfiguration;
            Settings = settings;
            Log = log;
            Migrator = migrator;

            MasterDbConnectionString = settings.GetConnectionString("master");

            var azCopyStorageParsed = Settings.AzureCopyStorageConnectionString.ToParsedAzureStorageConnection();
            _azureCopier = new AzureCopierFactory
            {
                Logger = Log,
                ImportExportSettings = new ImportExportSettings(azCopyStorageParsed["AccountKey"], azCopyStorageParsed["AccountName"], Settings.AzureCopyStorageContainer)
            };
        }
        private static void RunMigrations(string databaseName, TodoDbContext todoDbContext, ILogger logger)
        {
            logger.LogInformation("About to delete test database {TestDatabaseName} ...", databaseName);
            bool hasDeleteDatabase = todoDbContext.Database.EnsureDeleted();

            logger.LogInformation(
                hasDeleteDatabase
                    ? "Test database {TestDatabaseName} has been successfully deleted"
                    : "Could not find any test database {TestDatabaseName} to delete", databaseName);

            logger.LogInformation("About to run migrations against test database {TestDatabaseName} ...", databaseName);
            IMigrator databaseMigrator = todoDbContext.GetInfrastructure().GetRequiredService <IMigrator>();

            databaseMigrator.Migrate();
            logger.LogInformation("Migrations have been successfully run against test database {TestDatabaseName}",
                                  databaseName);
        }
        MigratorHarness()
        {
            var builder = new SqlConnectionStringBuilder
            {
                IntegratedSecurity = true,
                DataSource         = "(localdb)\\mssqllocaldb",
                InitialCatalog     = Guid.NewGuid().ToString()
            };

            _connectionString = builder.ConnectionString;
            _options          = new DbContextOptionsBuilder <TContext>()
                                .UseSqlServer(_connectionString)
                                .Options;

            _context  = (TContext)Activator.CreateInstance(typeof(TContext), _options);
            _migrator = _context.GetService <IMigrator>();
        }
示例#14
0
        private void DoImport(TCObject objectToExecuteOn)
        {
            foreach (XModule wseModule in objectToExecuteOn.GetWseModules())
            {
                try {
                    IMigrator migrator = MigratorFactory.GetMigrator(wseModule);
                    migrator.Migrate(objectToExecuteOn);
                }
                catch (Exception e) {
                    FileLogger.Instance.Error(
                        $"Migration of WSE Module 'migration for WSE Module :'{wseModule.DisplayedName}' failed due an error. This might leave the module in a inconsistent state.",
                        e);
                }
            }

            CommonUtilities.ReplaceResourceWithLastResponseResource(objectToExecuteOn);
        }
        public IntegrationTestDbFixture()
        {
            Console.WriteLine("Bootstrapper.Init()..");
            ClassFactory = Bootstrapper.Init();

            dbMigration = ClassFactory.GetMigrator(Environments.INTEGRATIONTEST);
            if (dbMigration == null)
            {
                throw new NoNullAllowedException("dbMigration not found..");
            }

            Console.WriteLine("DestroyDb if any..");
            dbMigration.DestroyDb();

            Console.WriteLine("CreateDb..");
            dbMigration.CreateDb(DB_DIRECTORY);
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public static void MigrationsNotApplied(
            [NotNull] this IDiagnosticsLogger <DbLoggerCategory.Migrations> diagnostics,
            [NotNull] IMigrator migrator)
        {
            var definition = RelationalStrings.LogNoMigrationsApplied;

            definition.Log(diagnostics);

            if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name))
            {
                diagnostics.DiagnosticSource.Write(
                    definition.EventId.Name,
                    new MigratorEventData(
                        definition,
                        (d, p) => ((EventDefinition)d).GenerateMessage(),
                        migrator));
            }
        }
示例#17
0
        public void StartMigration()
        {
            if (_Settings.SourceType == MigrationSourceType.ReIndexOnly)
            {
                ReIndex();
                return;
            }

            wl("Starting Migration at " + DateTime.UtcNow.ToString());
            wl("=====================================================");

            if (_Settings == null)
            {
                wl("Settings file can not be null");
                return;
            }
            DumpSettings();

            IMigrator migrator = null;

            switch (_Settings.SourceType)
            {
            case MigrationSourceType.MerchantTribe:
                migrator = new Migrators.MerchantTribe.Migrator();
                break;

            case MigrationSourceType.BV5:
                migrator = new Migrators.BV5.Migrator();
                break;

            case MigrationSourceType.BVC2004:
                migrator = new Migrators.BV2004.Migrator();
                break;
            }

            if (migrator != null)
            {
                migrator.ProgressReport += new ProgressReportDelegate(migrator_ProgressReport);
                migrator.Migrate(_Settings);
            }

            wl("Ending Migration at " + DateTime.UtcNow.ToString());
            wl("--EXIT--");
        }
示例#18
0
        public NpgsqlDatabaseFactory(
            [NotNull] DbContext context,
            [NotNull] INpgsqlDataStoreCreator dataStoreCreator,
            [NotNull] INpgsqlEFConnection connection,
            [NotNull] IMigrator migrator,
            [NotNull] ILoggerFactory loggerFactory)
        {
            Check.NotNull(context, nameof(context));
            Check.NotNull(dataStoreCreator, nameof(dataStoreCreator));
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(migrator, nameof(migrator));
            Check.NotNull(loggerFactory, nameof(loggerFactory));

            _context = context;
            _dataStoreCreator = dataStoreCreator;
            _connection = connection;
            _migrator = migrator;
            _loggerFactory = loggerFactory;
        }
        /// <summary>
        /// Applies pending migrations, if any.
        /// </summary>
        /// <param name="ep">The IEndPointConfiguration whose properties will be used as keys.</param>
        /// <returns>A list of names of migrations that were applied.</returns>
        public virtual async Task <List <string> > ApplyMigrations(IEndPointConfiguration endPoint)
        {
            DbContext            context         = resolver.ResolveMigrationContext(endPoint);
            IDatabaseInitializer dataInitializer = resolver.ResolveDatabaseInitializer(endPoint);

            List <string> migrations = (await context.Database.GetPendingMigrationsAsync()).ToList();
            IMigrator     migrator   = context.Database.GetService <IMigrator>();

            foreach (string migrationName in migrations)
            {
                await migrator.MigrateAsync(migrationName);

                if (dataInitializer != null)
                {
                    await dataInitializer.Seed(migrationName);
                }
            }
            return(migrations);
        }
        public RelationalDatabaseFactory(
            [NotNull] DbContext context,
            [NotNull] IRelationalDataStoreCreator dataStoreCreator,
            [NotNull] IRelationalConnection connection,
            [NotNull] IMigrator migrator,
            [NotNull] ILoggerFactory loggerFactory)
        {
            Check.NotNull(context, nameof(context));
            Check.NotNull(dataStoreCreator, nameof(dataStoreCreator));
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(migrator, nameof(migrator));
            Check.NotNull(loggerFactory, nameof(loggerFactory));

            _context          = context;
            _dataStoreCreator = dataStoreCreator;
            _connection       = connection;
            _migrator         = migrator;
            _loggerFactory    = loggerFactory;
        }
        public IntegrationTestDbFixture()
        {
            var configuration = ConfigBuilder.GetConfiguration();

            ExportDescriptorProvider instanceRegistration(ContainerConfiguration r) => r.WithInstance(configuration);

            ClassFactory = Bootstrapper.Init(instanceRegistration);
            dbMigration  = GetTestDbMigration();

            if (dbMigration == null)
            {
                throw new NoNullAllowedException("dbMigration not found..");
            }

            Console.WriteLine("DestroyDb if any..");
            dbMigration.DestroyDb();

            Console.WriteLine("CreateDb..");
            dbMigration.CreateDb(DB_DIRECTORY);
        }
示例#22
0
        public GenericFileDictionary(string fileName, IMigrator <T> migrator = null) : base(fileName)
        {
            string dbType       = typeof(T).ToString();
            bool   typeMismatch = !dbType.Equals(base.TypeInfo);

            if (typeMismatch && migrator == null)
            {
                throw new Exception("Wrong DB type and no migrator specified.");
            }
            else if (typeMismatch)
            {
                List <string> keys = base.Keys;
                foreach (string key in keys)
                {
                    string objectString = base[key] as string;
                    Add(key, migrator.Migrate(objectString));
                }
                base.TypeInfo = typeof(T).ToString();
            }
        }
示例#23
0
        public CollectorService(
            ILogger <CollectorService> logger,
            IMigrator migrator,
            ICollectorManager collectorManager,
            IHostApplicationLifetime appLifetime)
        {
            _logger                  = logger;
            _migrator                = migrator;
            _collectorManager        = collectorManager;
            _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(appLifetime.ApplicationStopping);
            _cancellationToken       = _cancellationTokenSource.Token;

            Environment.ExitCode = 1;

            _cancellationTokenSource.Token.Register(() =>
            {
                _logger.LogInformation($"Shutting down {nameof(CollectorService)}..");
                appLifetime.StopApplication();
            });
        }
示例#24
0
        public async Task GivenTheCurrentMigrations_WhenRunningThemInBothDirections_DatabaseIsCorrectlyMigrated()
        {
            // Arrange
            string databaseName =
                $"it--{nameof(GivenTheCurrentMigrations_WhenRunningThemInBothDirections_DatabaseIsCorrectlyMigrated)}";

            DbContextOptions <TodoDbContext> dbContextOptions = GetDbContextOptions(databaseName);

            await using TodoDbContext todoDbContext = new TodoDbContext(dbContextOptions);
            bool isMigrationSuccessful;

            try
            {
                await todoDbContext.Database.EnsureDeletedAsync();

                IMigrator databaseMigrator = todoDbContext.GetInfrastructure().GetRequiredService <IMigrator>();

                // Act
                await databaseMigrator.MigrateAsync();

                // Revert migrations by using a special migration identifier.
                // See more here: https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-database-update.
                await databaseMigrator.MigrateAsync(BeforeFirstDatabaseMigration);

                await databaseMigrator.MigrateAsync();

                isMigrationSuccessful = true;
            }
            catch
            {
                isMigrationSuccessful = false;
            }
            finally
            {
                await todoDbContext.Database.EnsureDeletedAsync();
            }

            // Assert
            isMigrationSuccessful.Should().BeTrue("migrations should work in both directions, up and down");
        }
        private static void RunMigrations(string databaseName, TodoDbContext todoDbContext, ILogger logger)
        {
            logger.LogInformation("About to delete test database {TestDatabaseName} ...", databaseName);
            bool hasDeleteDatabase = todoDbContext.Database.EnsureDeleted();

            // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
            if (hasDeleteDatabase)
            {
                logger.LogInformation("Test database {TestDatabaseName} has been successfully deleted", databaseName);
            }
            else
            {
                logger.LogInformation("Could not find any test database {TestDatabaseName} to delete", databaseName);
            }

            logger.LogInformation("About to run migrations against test database {TestDatabaseName} ...", databaseName);
            IMigrator databaseMigrator = todoDbContext.GetInfrastructure().GetRequiredService <IMigrator>();

            databaseMigrator.Migrate();
            logger.LogInformation("Migrations have been successfully run against test database {TestDatabaseName}",
                                  databaseName);
        }
        public MigrationsScaffolderDependencies(
            [NotNull] ICurrentDbContext currentContext,
            [NotNull] IModel model,
            [NotNull] IMigrationsAssembly migrationsAssembly,
            [NotNull] IMigrationsModelDiffer migrationsModelDiffer,
            [NotNull] IMigrationsIdGenerator migrationsIdGenerator,
            [NotNull] IMigrationsCodeGeneratorSelector migrationsCodeGeneratorSelector,
            [NotNull] IHistoryRepository historyRepository,
            [NotNull] IOperationReporter operationReporter,
            [NotNull] IDatabaseProvider databaseProvider,
            [NotNull] ISnapshotModelProcessor snapshotModelProcessor,
            [NotNull] IMigrator migrator)
        {
            Check.NotNull(currentContext, nameof(currentContext));
            Check.NotNull(model, nameof(model));
            Check.NotNull(migrationsAssembly, nameof(migrationsAssembly));
            Check.NotNull(migrationsModelDiffer, nameof(migrationsModelDiffer));
            Check.NotNull(migrationsIdGenerator, nameof(migrationsIdGenerator));
            Check.NotNull(migrationsCodeGeneratorSelector, nameof(migrationsCodeGeneratorSelector));
            Check.NotNull(historyRepository, nameof(historyRepository));
            Check.NotNull(operationReporter, nameof(operationReporter));
            Check.NotNull(databaseProvider, nameof(databaseProvider));
            Check.NotNull(snapshotModelProcessor, nameof(snapshotModelProcessor));
            Check.NotNull(migrator, nameof(migrator));

            CurrentContext                  = currentContext;
            Model                           = model;
            MigrationsAssembly              = migrationsAssembly;
            MigrationsModelDiffer           = migrationsModelDiffer;
            MigrationsIdGenerator           = migrationsIdGenerator;
            MigrationsCodeGeneratorSelector = migrationsCodeGeneratorSelector;
            HistoryRepository               = historyRepository;
            OperationReporter               = operationReporter;
            DatabaseProvider                = databaseProvider;
            SnapshotModelProcessor          = snapshotModelProcessor;
            Migrator                        = migrator;
        }
        public HeatingControl(IApplicationLifetime appLifetime,
                              IMigrator migrator,
                              IBuildingProvider buildingProvider,
                              IControllerStateBuilder controllerStateBuilder,
                              ICommandExecutor <DisableAllOutputsCommand> disableAllOutputsCommandExecutor,
                              ITemperatureReadingLoop temperatureReadingLoop,
                              IScheduleDeterminationLoop scheduleDeterminationLoop,
                              IOutputStateProcessingLoop outputStateProcessingLoop,
                              IDigitalInputReadingLoop digitalInputReadingLoop)
        {
            migrator.Run();

            _appLifetime      = appLifetime;
            _buildingProvider = buildingProvider;
            _disableAllOutputsCommandExecutor = disableAllOutputsCommandExecutor;
            _temperatureReadingLoop           = temperatureReadingLoop;
            _scheduleDeterminationLoop        = scheduleDeterminationLoop;
            _outputStateProcessingLoop        = outputStateProcessingLoop;
            _digitalInputReadingLoop          = digitalInputReadingLoop;

            var model = _buildingProvider.ProvideDefault();

            State = controllerStateBuilder.Build(model);
        }
示例#28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MandarinDbContext"/> class.
 /// </summary>
 /// <param name="configuration">Application configuration for configuring services.</param>
 /// <param name="migrator">The service for upgrading the database schema.</param>
 public MandarinDbContext(IConfiguration configuration, IMigrator migrator)
 {
     this.configuration = configuration;
     this.migrator      = migrator;
 }
 public Serializer(IMigrator migrator, ISerializer serializer)
 {
     _migrator   = migrator;
     _serializer = serializer;
 }
示例#30
0
 public GeneralMigrationPolicy(IFilePolicy filePolicy, IMigrator migrator)
 {
     _filePolicy = filePolicy;
     _migrator = migrator;
 }
示例#31
0
 public Uploader(IMigrator migrator)
 {
     _migrator = migrator;
     _uploadWindow = new UploadWindow();
 }
示例#32
0
 public SystemController(IMigrator migrator, ILogger logger)
 {
     _migrator = migrator;
     _logger   = logger;
 }
 public TemporalTableMigratorResolver(IEnumerable <ITemporalTableMigrator> temporalTableMigrators, ICurrentDbContext currentDbContext)
 {
     CurrentTemporalTableMigrator = temporalTableMigrators.LastOrDefault(m => ReflectiveTemporalTableManager(currentDbContext).IsAssignableFrom(m.GetType()));
 }
 public ContractBusinessRuleActivity WithMigrator(IMigrator parentMigrator)
 {
     Migrator = parentMigrator;
     return(this);
 }
        public async Task SaveChanges_WhenModifyingSameEntityUsingTwoConcurrentTransactions_ThrowsException()
        {
            // Arrange
            string databaseName =
                $"it--{nameof(SaveChanges_WhenModifyingSameEntityUsingTwoConcurrentTransactions_ThrowsException)}";
            DbContextOptions <TodoDbContext> dbContextOptions = GetDbContextOptions(databaseName);

            await using TodoDbContext firstTodoDbContext = new TodoDbContext(dbContextOptions);
            IMigrator databaseMigrator = firstTodoDbContext.GetInfrastructure().GetRequiredService <IMigrator>();
            await databaseMigrator.MigrateAsync();

            try
            {
                string name = "ConcurrentlyAccessedTodoItem";

                TodoItem todoItem = new TodoItem(name, "it")
                {
                    IsComplete = false,
                };

                await firstTodoDbContext.TodoItems.AddAsync(todoItem);

                await firstTodoDbContext.SaveChangesAsync();

                await using IDbContextTransaction firstTransaction =
                                await firstTodoDbContext.Database.BeginTransactionAsync();

                TodoItem todoItemFromFirstTransaction =
                    await firstTodoDbContext.TodoItems.FirstAsync(x => x.Name == name);

                todoItemFromFirstTransaction.IsComplete    = true;
                todoItemFromFirstTransaction.LastUpdatedBy = Guid.NewGuid().ToString("N");
                todoItemFromFirstTransaction.LastUpdatedOn = DateTime.UtcNow;

                await using TodoDbContext secondTodoDbContext       = new TodoDbContext(dbContextOptions);
                await using IDbContextTransaction secondTransaction =
                                await secondTodoDbContext.Database.BeginTransactionAsync();

                TodoItem todoItemFromSecondTransaction =
                    await secondTodoDbContext.TodoItems.FirstAsync(x => x.Name == name);

                todoItemFromSecondTransaction.IsComplete    = false;
                todoItemFromSecondTransaction.LastUpdatedBy = Guid.NewGuid().ToString("N");
                todoItemFromSecondTransaction.LastUpdatedOn = DateTime.UtcNow;

                await firstTodoDbContext.SaveChangesAsync();

                await firstTransaction.CommitAsync();

                // Act
                Func <Task> saveChangesAsyncCall = async() =>
                {
                    // ReSharper disable AccessToDisposedClosure
                    await secondTodoDbContext.SaveChangesAsync();

                    await secondTransaction.CommitAsync();

                    // ReSharper restore AccessToDisposedClosure
                };

                // Assert
                saveChangesAsyncCall.Should()
                .ThrowExactly <DbUpdateConcurrencyException>(
                    "2 transactions were concurrently modifying the same entity");
            }
            finally
            {
                await firstTodoDbContext.Database.EnsureDeletedAsync();
            }
        }