public void Design_time_works()
        {
            var services = new DesignTimeServicesBuilder(
                typeof(EndToEndTests).Assembly,
                typeof(EndToEndTests).Assembly,
                new OperationReporter(null),
                Array.Empty <string>())
                           .Build("Microsoft.EntityFrameworkCore.Sqlite");

            var namedConnectionStringResolver = services.GetService <INamedConnectionStringResolver>();

            Assert.IsType <ConfigrationManagerConnectionStringResolver>(namedConnectionStringResolver);
        }
Пример #2
0
        /// <summary>
        /// Automatically migrate the database
        /// Note: The DbContext to be migrated needs to inherit from IKingsDbContext or manually add entity MigrationLog in any way.
        /// </summary>
        /// <param name="dbContext"></param>
        public static void AutoMigratorDatabase(this DbContext dbContext)
        {
            Console.WriteLine($"database begin to magration ......");
            IModel lastModel = null;

            try
            {
                var relationDatabase = dbContext.GetService <IRelationalDatabaseCreator>();
                if (!relationDatabase.Exists())
                {
                    relationDatabase.Create();
                }
                else
                {
                    var lastMigration = dbContext.Set <MigrationLog>()
                                        .OrderByDescending(e => e.Id)
                                        .FirstOrDefault();
                    lastModel = lastMigration == null ? null : (CreateModelSnapshot(lastMigration.SnapshotDefine, typeof(DbContextMigrationExtensions).Namespace
                                                                                    , _dbContentModelSnapshot, dbContext.GetType())?.Model);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            var modelDiffer = dbContext.Database.GetService <IMigrationsModelDiffer>();

            if (modelDiffer.HasDifferences(lastModel, dbContext.Model))
            {
                var upOperations = modelDiffer.GetDifferences(lastModel, dbContext.Model);
                Migrationing(upOperations, dbContext);

                var serviceProvider = new DesignTimeServicesBuilder(dbContext.GetType().Assembly,
                                                                    Assembly.GetEntryAssembly(),
                                                                    new OperationReporter(new OperationReportHandler()), new string[0])
                                      .Build(dbContext);
                var migrationsCodeGenerator = serviceProvider.GetService(typeof(IMigrationsCodeGenerator)) as IMigrationsCodeGenerator;
                var snapshotCode            = migrationsCodeGenerator.GenerateSnapshot(typeof(DbContextMigrationExtensions).Namespace, dbContext.GetType(), _dbContentModelSnapshot, dbContext.Model);
                dbContext.Set <MigrationLog>().Add(new MigrationLog()
                {
                    SnapshotDefine = snapshotCode,
                    MigrationTime  = DateTime.Now
                });
                dbContext.SaveChanges();
            }
            Console.WriteLine($"database magration end......");
        }
Пример #3
0
        public async Task RunAsync(IDbContext context)
        {
            IModel lastModel = null;
            var    contextServiceProvider = context.Context.GetInfrastructure();

            var store = context.Context.GetService <IStore>();

            await new InitlizationDbContext(store.CreateOptions(false)).Database.EnsureCreatedAsync();

            try
            {
                var lastMigration = context.Migrations
                                    .OrderByDescending(e => e.MigrationTime)
                                    .OrderByDescending(e => e.Id) // mysql下自动生成的时间日期字段时间精度为秒
                                    .FirstOrDefault();
                lastModel = lastMigration == null ? null : ((await CreateModelSnapshot(context, Encoding.UTF8.GetString(Convert.FromBase64String(lastMigration.SnapshotDefine))))?.Model);
            }
            catch (DbException) { }

            var designTimeServices = new DesignTimeServicesBuilder(
                context.Context.GetType().Assembly,
                context.Context.GetType().Assembly,
                new OperationReporter(),
                new string[0]).Build(context.Context);
            var process = designTimeServices.GetService <ISnapshotModelProcessor>();

            // 需要从历史版本库中取出快照定义,反序列化成类型 GetDifferences(快照模型, context.Model);
            // 实际情况下要传入历史快照
            var modelDiffer = contextServiceProvider.GetService <IMigrationsModelDiffer>();
            var hasDiffer   = modelDiffer.HasDifferences(
                lastModel != null ? process.Process(lastModel).GetRelationalModel() : null,
                context.Context.Model.GetRelationalModel());

            if (!hasDiffer)
            {
                return;
            }

            var upOperations = modelDiffer.GetDifferences(
                lastModel != null ? lastModel.GetRelationalModel() : null,
                context.Context.Model.GetRelationalModel());

            using (var trans = context.Context.Database.BeginTransaction())
            {
                try
                {
                    contextServiceProvider.GetRequiredService <IMigrationsSqlGenerator>()
                    .Generate(upOperations, context.Context.Model)
                    .ToList()
                    .ForEach(cmd => context.Context.Database.ExecuteSqlRaw(cmd.CommandText));

                    trans.Commit();
                }
                catch (DbException ex)
                {
                    trans.Rollback();
                    throw ex;
                }

                context.Migrations.Add(new MigrationRecord()
                {
                    SnapshotDefine = await CreateSnapshotCode(designTimeServices, context),
                    MigrationTime  = DateTime.Now
                });

                await context.Context.SaveChangesAsync(true);
            }
        }