internal DatabaseChanges(Database oldDatabase, DestinationDatabase newDatabase, IList<TableChanges> tableChanges) { this.OldDatabase = oldDatabase; this.NewDatabase = newDatabase; this.ChangeType = ChangeType.UnChanged; if (!oldDatabase.Removed || !newDatabase.Removed) { if (oldDatabase.Removed) { this.ChangeType = ChangeType.Added; return; } if (newDatabase.Removed) { this.ChangeType = ChangeType.Removed; return; } if (tableChanges != null && tableChanges.Count > 0) { this.ChangeType = ChangeType.Modified; this._allRecords = tableChanges; } } }
internal DatabaseChanges(Database oldDatabase, DestinationDatabase newDatabase, IList <TableChanges> tableChanges) { this.OldDatabase = oldDatabase; this.NewDatabase = newDatabase; this.ChangeType = ChangeType.UnChanged; if (!oldDatabase.Removed || !newDatabase.Removed) { if (oldDatabase.Removed) { this.ChangeType = ChangeType.Added; return; } if (newDatabase.Removed) { this.ChangeType = ChangeType.Removed; return; } if (tableChanges != null && tableChanges.Count > 0) { this.ChangeType = ChangeType.Modified; this._allRecords = tableChanges; } } }
/// <summary> /// 计算出两个数据库元数据的所有表差别 /// </summary> /// <param name="oldDatabase">旧数据库</param> /// <param name="newDatabase">新数据库</param> /// <returns></returns> public static DatabaseChanges Distinguish(Database oldDatabase, DestinationDatabase newDatabase) { if (!oldDatabase.Removed) { oldDatabase.OrderByRelations(); } if (!newDatabase.Removed) { newDatabase.OrderByRelations(); } List <TableChanges> result = new List <TableChanges>(); if (!oldDatabase.Removed && !newDatabase.Removed) { //先找出所有被删除的表 foreach (var oldTable in oldDatabase.Tables.Reverse()) { if (newDatabase.FindTable(oldTable.Name) == null && !newDatabase.IsIgnored(oldTable.Name)) { result.Add(new TableChanges(oldTable, null, ChangeType.Removed)); } } foreach (var newTable in newDatabase.Tables) { if (!newDatabase.IsIgnored(newTable.Name)) { var oldTable = oldDatabase.FindTable(newTable.Name); //如果没有找到旧表,说明这个表是新加的。 if (oldTable == null) { result.Add(new TableChanges(null, newTable, ChangeType.Added)); } else { //即不是新表,也不是旧表,计算两个表的区别 TableChanges record = Distinguish(oldTable, newTable); //如果有区别,则记录下来 if (record != null) { result.Add(record); } } } } } return(new DatabaseChanges(oldDatabase, newDatabase, result)); }
/// <summary> /// 计算出两个数据库元数据的所有表差别 /// </summary> /// <param name="oldDatabase">旧数据库</param> /// <param name="newDatabase">新数据库</param> /// <returns></returns> public static DatabaseChanges Distinguish(Database oldDatabase, DestinationDatabase newDatabase) { if (!oldDatabase.Removed) { oldDatabase.OrderByRelations(); } if (!newDatabase.Removed) { newDatabase.OrderByRelations(); } List<TableChanges> result = new List<TableChanges>(); if (!oldDatabase.Removed && !newDatabase.Removed) { //先找出所有被删除的表 foreach (var oldTable in oldDatabase.Tables.Reverse()) { if (newDatabase.FindTable(oldTable.Name) == null && !newDatabase.IsIgnored(oldTable.Name)) { result.Add(new TableChanges(oldTable, null, ChangeType.Removed)); } } foreach (var newTable in newDatabase.Tables) { if (!newDatabase.IsIgnored(newTable.Name)) { var oldTable = oldDatabase.FindTable(newTable.Name); //如果没有找到旧表,说明这个表是新加的。 if (oldTable == null) { result.Add(new TableChanges(null, newTable, ChangeType.Added)); } else { //即不是新表,也不是旧表,计算两个表的区别 TableChanges record = Distinguish(oldTable, newTable); //如果有区别,则记录下来 if (record != null) { result.Add(record); } } } } } return new DatabaseChanges(oldDatabase, newDatabase, result); }
public DestinationDatabase Read() { var tableEntityTypes = this.GetMappingEntityTypes(); var result = new DestinationDatabase(this._dbSetting.Database); foreach (var item in this.IgnoreTables) { result.IgnoreTables.Add(item); } if (tableEntityTypes.Count == 0) { result.Removed = true; } else { var reader = new TypesMetaReader { Database = result, Entities = tableEntityTypes }; reader.Read(); } return result; }
/// <summary> /// 自动移植到目标结构 /// 注意,自动迁移时,同样执行相应时间段的手工迁移。 /// </summary> /// <param name="destination">目标结构</param> public void MigrateTo(DestinationDatabase destination) { /*********************** 代码块解释 ********************************* * * 主要更新逻辑如下: * 1 根据当前版本号,同步最新的历史记录。 * 客户端被动升级:当给客户版本做更新时,一般使用开发人员的历史记录替换客户版本的历史记录,此时发生此逻辑: * 发现历史记录中有比当前数据库版本还要新的记录时,说明已经使用了最新版本的历史记录库,这时需要根据这些历史记录来升级数据库。 * 2 如果是第一次创建库,则:先执行自动升级、然后再执行手工结构升级。 * 2 如果是升级库,则:先执行手工结构升级、然后再执行自动升级。 * 3 执行手工数据升级。 * **********************************************************************/ if (this.SupportHistory) { Must(this.MigrateToHistory(DateTime.MaxValue)); } var manualPendings = this.GetManualPendings(); var schemaPending = manualPendings.Where(m => m.Type == ManualMigrationType.Schema).ToList(); var dataPending = manualPendings.Where(m => m.Type == ManualMigrationType.Data).ToList(); var dbMeta = this.DatabaseMetaReader.Read(); var changeSet = ModelDiffer.Distinguish(dbMeta, destination); //判断是否正处于升级阶段。(或者是处于创建阶段。) //不能直接用 dbMeta.Tables.Count > 0 来判断,这是因为里面可能有 IgnoreTables 中指定表。 var updating = changeSet.ChangeType == ChangeType.Removed || changeSet.ChangeType == ChangeType.Modified && changeSet.TablesChanged.Count(t => t.ChangeType == ChangeType.Added) < destination.Tables.Count; if (updating) { Must(this.MigrateUpBatch(schemaPending)); Must(this.AutoMigrate(changeSet)); } else { if (manualPendings.Count > 0) { //此时,自动升级的时间都应该小于所有手工升级 Must(this.AutoMigrate(changeSet, manualPendings[0].TimeId)); } else { Must(this.AutoMigrate(changeSet)); } Must(this.MigrateUpBatch(schemaPending)); } if (dataPending.Count > 0) { /*********************** 代码块解释 ********************************* * * 由于之前把 结构升级 和 数据升级 分离开了, * 所以有可能出现 数据升级 中的最后时间其实没有之前的 结构升级 或者 自动升级 的时间大, * 这样就会导致 数据升级 后,版本号变得更小了。 * 所以这里需要判断如果这种情况发生,则忽略数据升级中的版本号。 * **********************************************************************/ var dbVersion = this.GetDbVersion(); var maxDataPending = dataPending.Max(m => m.TimeId); Must(this.MigrateUpBatch(dataPending)); if (dbVersion > maxDataPending) { this.DbVersionProvider.SetDbVersion(dbVersion); } } }