Exemple #1
0
        public void ModixContext_Always_ModelMatchesMigrationsSnapshot()
        {
            var optionsBuilder = new DbContextOptionsBuilder <ModixContext>()
                                 .UseNpgsql("Bogus connection string: we don't actually need to connect to the DB, just build ourselves a model.");

            var context = new ModixContext(optionsBuilder.Options);

            var migrationsAssembly     = context.GetService <IMigrationsAssembly>();
            var dependencies           = context.GetService <ProviderConventionSetBuilderDependencies>();
            var relationalDependencies = context.GetService <RelationalConventionSetBuilderDependencies>();
            var modelDiffer            = context.GetService <IMigrationsModelDiffer>();

            var hasDifferences = false;

            if (migrationsAssembly.ModelSnapshot != null)
            {
                var typeMappingConvention = new TypeMappingConvention(dependencies);
                typeMappingConvention.ProcessModelFinalizing(((IConventionModel)migrationsAssembly.ModelSnapshot.Model).Builder, null !);

                var relationalModelConvention = new RelationalModelConvention(dependencies, relationalDependencies);
                var sourceModel = relationalModelConvention.ProcessModelFinalized(migrationsAssembly.ModelSnapshot.Model);

                hasDifferences = modelDiffer.HasDifferences(
                    ((IMutableModel)sourceModel).FinalizeModel().GetRelationalModel(),
                    context.Model.GetRelationalModel());
            }

            hasDifferences.ShouldBeFalse();
        }
        public async Task PendingModelChangesTest()
        {
            var dummyConnectionString  = "Host=localhost;Database=nxplx_db;Username=postgres;Password=dev";
            var databaseContextOptions = new DbContextOptionsBuilder <DatabaseContext>().UseNpgsql(dummyConnectionString,
                                                                                                   b => b.MigrationsAssembly(typeof(DatabaseContext).Assembly.FullName)).Options;

            await using var databaseContext = new DatabaseContext(databaseContextOptions, new OperationContext());

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

            var dependencies           = databaseContext.GetService <ProviderConventionSetBuilderDependencies>();
            var relationalDependencies = databaseContext.GetService <RelationalConventionSetBuilderDependencies>();

            var typeMappingConvention = new TypeMappingConvention(dependencies);

            typeMappingConvention.ProcessModelFinalizing(((IConventionModel)migrationsAssembly.ModelSnapshot.Model).Builder, null);

            var relationalModelConvention = new RelationalModelConvention(dependencies, relationalDependencies);
            var sourceModel = relationalModelConvention.ProcessModelFinalized(migrationsAssembly.ModelSnapshot.Model);

            var finalSourceModel = ((IMutableModel)sourceModel).FinalizeModel().GetRelationalModel();
            var finalTargetModel = databaseContext.Model.GetRelationalModel();

            var differences = modelDiffer.GetDifferences(finalSourceModel, finalTargetModel);

            if (differences.Any())
            {
                Assert.True(false, $"{differences.Count} changes between migrations and model. Debug this test for more details");
            }

            Assert.Pass();
        }
        protected virtual void DiffSnapshot(ModelSnapshot snapshot, DbContext context)
        {
            var dependencies          = context.GetService <ProviderConventionSetBuilderDependencies>();
            var typeMappingConvention = new TypeMappingConvention(dependencies);

            typeMappingConvention.ProcessModelFinalizing(((IConventionModel)snapshot.Model).Builder, null);

            var relationalModelConvention = new RelationalModelConvention();
            var sourceModel = relationalModelConvention.ProcessModelFinalized(snapshot.Model);

            var modelDiffer = context.GetService <IMigrationsModelDiffer>();
            var operations  = modelDiffer.GetDifferences(((IMutableModel)sourceModel).FinalizeModel(), context.Model);

            Assert.Equal(0, operations.Count);
        }
Exemple #4
0
        public void TestNoDbMigrationNeeded()
        {
            using var dbContext = new MemCheckDbContext(new DbContextOptionsBuilder <MemCheckDbContext>().UseSqlServer(@"Server=none;Database=none;Trusted_Connection=True;").Options);

            var relationalDependencies    = dbContext.GetService <RelationalConventionSetBuilderDependencies>();
            var relationalModelConvention = new RelationalModelConvention(dbContext.GetService <ProviderConventionSetBuilderDependencies>(), relationalDependencies);
            var modelSnapshot             = (IConventionModel)dbContext.GetService <IMigrationsAssembly>().ModelSnapshot.Model;
            var finalizedSnapshotModel    = relationalModelConvention.ProcessModelFinalized(modelSnapshot).GetRelationalModel();

            var possiblyModifiedModel = dbContext.Model.GetRelationalModel();

            var changes = dbContext.GetService <IMigrationsModelDiffer>().GetDifferences(finalizedSnapshotModel, possiblyModifiedModel);

            Assert.AreEqual(0, changes.Count, "A DB model update is needed - Run dotnet ef migrations add - " + string.Join(',', changes.Select(change => change.ToString())));
        }
Exemple #5
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual IModel Process(IModel model)
        {
            if (model == null)
            {
                return(null);
            }

            var version = model.GetProductVersion();

            if (version != null)
            {
                ProcessElement(model, version);

                foreach (var entityType in model.GetEntityTypes())
                {
                    ProcessElement(entityType, version);
                    ProcessCollection(entityType.GetProperties(), version);
                    ProcessCollection(entityType.GetKeys(), version);
                    ProcessCollection(entityType.GetIndexes(), version);

                    foreach (var element in entityType.GetForeignKeys())
                    {
                        ProcessElement(element, version);
                        ProcessElement(element.DependentToPrincipal, version);
                        ProcessElement(element.PrincipalToDependent, version);
                    }
                }
            }

            if (model is IConventionModel conventionModel &&
                _conventionDependencies != null)
            {
                var typeMappingConvention = new TypeMappingConvention(_conventionDependencies);
                typeMappingConvention.ProcessModelFinalizing(conventionModel.Builder, null);

                model = new RelationalModelConvention().ProcessModelFinalized(conventionModel);
            }

            return(model is IMutableModel mutableModel
                ? mutableModel.FinalizeModel()
                : model);
        }
        private string GetMigrationStatus(DbContext context)
        {
            var relationalDatabaseCreator = context.GetService <IDatabaseCreator>() as IRelationalDatabaseCreator;

            if (relationalDatabaseCreator == null)
            {
                throw new Exception("Not a relational database, migrations are not supported");
            }
            var databaseExists = relationalDatabaseCreator.Exists();

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

#if CORE50
            var dependencies           = context.GetService <ProviderConventionSetBuilderDependencies>();
            var relationalDependencies = context.GetService <RelationalConventionSetBuilderDependencies>();

            var hasDifferences = false;

            if (migrationsAssembly.ModelSnapshot != null)
            {
                var typeMappingConvention = new TypeMappingConvention(dependencies);
                typeMappingConvention.ProcessModelFinalizing(((IConventionModel)migrationsAssembly.ModelSnapshot.Model).Builder, null);

                var relationalModelConvention = new RelationalModelConvention(dependencies, relationalDependencies);
                var sourceModel = relationalModelConvention.ProcessModelFinalized(migrationsAssembly.ModelSnapshot.Model);

                hasDifferences = modelDiffer.HasDifferences(
                    ((IMutableModel)sourceModel).FinalizeModel().GetRelationalModel(),
                    context.Model.GetRelationalModel());
            }

            var pendingModelChanges = (!databaseExists || hasDifferences);
#else
            var pendingModelChanges
                = (!databaseExists || migrationsAssembly.ModelSnapshot != null) &&
                  modelDiffer.HasDifferences(migrationsAssembly.ModelSnapshot?.Model, context.Model);
#endif
            if (pendingModelChanges)
            {
                return("Changes");
            }

            var migrations = context.Database.GetMigrations().ToArray();

            if (!migrations.Any())
            {
                return("NoMigrations");
            }

            var pendingMigrations
                = (databaseExists
                    ? context.Database.GetPendingMigrations()
                    : migrations)
                  .ToArray();

            if (pendingMigrations.Any())
            {
                return("Pending");
            }

            return("InSync");
        }
        private IMigrationsScaffolder CreateMigrationScaffolder <TContext>()
            where TContext : DbContext, new()
        {
            var currentContext             = new CurrentDbContext(new TContext());
            var idGenerator                = new MigrationsIdGenerator();
            var sqlServerTypeMappingSource = new SqlServerTypeMappingSource(
                TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
                TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>());
            var code     = new CSharpHelper(sqlServerTypeMappingSource);
            var reporter = new TestOperationReporter();
            var migrationAssembly
                = new MigrationsAssembly(
                      currentContext,
                      new DbContextOptions <TContext>().WithExtension(new FakeRelationalOptionsExtension()),
                      idGenerator,
                      new FakeDiagnosticsLogger <DbLoggerCategory.Migrations>());
            var historyRepository = new MockHistoryRepository();

            var    services = RelationalTestHelpers.Instance.CreateContextServices();
            IModel model    = new Model();

            model = new RelationalModelConvention().ProcessModelFinalized(model);

            return(new MigrationsScaffolder(
                       new MigrationsScaffolderDependencies(
                           currentContext,
                           model,
                           migrationAssembly,
                           new MigrationsModelDiffer(
                               new TestRelationalTypeMappingSource(
                                   TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
                                   TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>()),
                               new MigrationsAnnotationProvider(new MigrationsAnnotationProviderDependencies()),
                               services.GetRequiredService <IChangeDetector>(),
                               services.GetRequiredService <IUpdateAdapterFactory>(),
                               services.GetRequiredService <CommandBatchPreparerDependencies>()),
                           idGenerator,
                           new MigrationsCodeGeneratorSelector(
                               new[]
            {
                new CSharpMigrationsGenerator(
                    new MigrationsCodeGeneratorDependencies(sqlServerTypeMappingSource),
                    new CSharpMigrationsGeneratorDependencies(
                        code,
                        new CSharpMigrationOperationGenerator(
                            new CSharpMigrationOperationGeneratorDependencies(
                                code)),
                        new CSharpSnapshotGenerator(
                            new CSharpSnapshotGeneratorDependencies(
                                code, sqlServerTypeMappingSource))))
            }),
                           historyRepository,
                           reporter,
                           new MockProvider(),
                           new SnapshotModelProcessor(reporter),
                           new Migrator(
                               migrationAssembly,
                               historyRepository,
                               services.GetRequiredService <IDatabaseCreator>(),
                               services.GetRequiredService <IMigrationsSqlGenerator>(),
                               services.GetRequiredService <IRawSqlCommandBuilder>(),
                               services.GetRequiredService <IMigrationCommandExecutor>(),
                               services.GetRequiredService <IRelationalConnection>(),
                               services.GetRequiredService <ISqlGenerationHelper>(),
                               services.GetRequiredService <ICurrentDbContext>(),
                               services.GetRequiredService <IDiagnosticsLogger <DbLoggerCategory.Migrations> >(),
                               services.GetRequiredService <IDiagnosticsLogger <DbLoggerCategory.Database.Command> >(),
                               services.GetRequiredService <IDatabaseProvider>()))));
        }