private async Task InternalConvert(SchemaInfo schemaInfo = null, bool getAllIfNotSpecified = true, bool async = false) { DbInterpreter sourceInterpreter = this.Source.DbInterpreter; sourceInterpreter.Option.TreatBytesAsNullForScript = true; string[] tableNames = null; string[] userDefinedTypeNames = null; string[] viewNames = null; if (schemaInfo == null || getAllIfNotSpecified) { tableNames = sourceInterpreter.GetTables().Select(item => item.Name).ToArray(); userDefinedTypeNames = sourceInterpreter.GetUserDefinedTypes().Select(item => item.Name).ToArray(); viewNames = sourceInterpreter.GetViews().Select(item => item.Name).ToArray(); } else { tableNames = schemaInfo.Tables.Select(t => t.Name).ToArray(); userDefinedTypeNames = schemaInfo.UserDefinedTypes.Select(item => item.Name).ToArray(); viewNames = schemaInfo.Views.Select(item => item.Name).ToArray(); } SelectionInfo selectionInfo = new SelectionInfo() { UserDefinedTypeNames = userDefinedTypeNames, TableNames = tableNames, ViewNames = viewNames }; SchemaInfo sourceSchemaInfo = async? await sourceInterpreter.GetSchemaInfoAsync(selectionInfo, getAllIfNotSpecified): sourceInterpreter.GetSchemaInfo(selectionInfo, getAllIfNotSpecified); SchemaInfo targetSchemaInfo = SchemaInfoHelper.Clone(sourceSchemaInfo); if (!string.IsNullOrEmpty(this.Target.DbOwner)) { SchemaInfoHelper.TransformOwner(targetSchemaInfo, this.Target.DbOwner); } targetSchemaInfo.Columns = ColumnTranslator.Translate(targetSchemaInfo.Columns, this.Source.DbInterpreter.DatabaseType, this.Target.DbInterpreter.DatabaseType); targetSchemaInfo.Views = ViewTranslator.Translate(targetSchemaInfo.Views, sourceInterpreter, this.Target.DbInterpreter, this.Target.DbOwner); if (this.Option.EnsurePrimaryKeyNameUnique) { SchemaInfoHelper.EnsurePrimaryKeyNameUnique(targetSchemaInfo); } if (this.Option.EnsureIndexNameUnique) { SchemaInfoHelper.EnsureIndexNameUnique(targetSchemaInfo); } DbInterpreter targetInterpreter = this.Target.DbInterpreter; bool generateIdentity = targetInterpreter.Option.GenerateIdentity; if (generateIdentity) { targetInterpreter.Option.InsertIdentityValue = true; } string script = ""; sourceInterpreter.Subscribe(this); targetInterpreter.Subscribe(this); if (this.Option.GenerateScriptMode.HasFlag(GenerateScriptMode.Schema)) { script = targetInterpreter.GenerateSchemaScripts(targetSchemaInfo); if (string.IsNullOrEmpty(script)) { throw new Exception($"The script to create schema is null."); } targetInterpreter.Feedback(FeedbackInfoType.Info, "Begin to sync schema..."); if (!this.Option.SplitScriptsToExecute) { if (targetInterpreter is SqlServerInterpreter) { string[] scriptItems = script.Split(new string[] { "GO" + Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); if (async) { scriptItems.ToList().ForEach(async item => { await targetInterpreter.ExecuteNonQueryAsync(item); }); } else { scriptItems.ToList().ForEach(item => { targetInterpreter.ExecuteNonQuery(item); }); } } else { if (async) { await targetInterpreter.ExecuteNonQueryAsync(script); } else { targetInterpreter.ExecuteNonQuery(script); } } } else { string[] sqls = script.Split(new char[] { this.Option.ScriptSplitChar }, StringSplitOptions.RemoveEmptyEntries); int count = sqls.Count(); int i = 0; foreach (string sql in sqls) { if (!string.IsNullOrEmpty(sql.Trim())) { i++; targetInterpreter.Feedback(FeedbackInfoType.Info, $"({i}/{count}), executing {sql}"); targetInterpreter.ExecuteNonQuery(sql.Trim()); } } } targetInterpreter.Feedback(FeedbackInfoType.Info, "End sync schema."); } if (this.Option.GenerateScriptMode.HasFlag(GenerateScriptMode.Data)) { List <TableColumn> identityTableColumns = new List <TableColumn>(); if (generateIdentity) { identityTableColumns = targetSchemaInfo.Columns.Where(item => item.IsIdentity).ToList(); } if (this.Option.PickupTable != null) { sourceSchemaInfo.PickupTable = this.Option.PickupTable; } sourceInterpreter.AppendScriptsToFile("", GenerateScriptMode.Data, true); targetInterpreter.AppendScriptsToFile("", GenerateScriptMode.Data, true); using (DbConnection dbConnection = targetInterpreter.GetDbConnector().CreateConnection()) { identityTableColumns.ForEach(item => { if (targetInterpreter.DatabaseType == DatabaseType.SqlServer) { targetInterpreter.SetIdentityEnabled(dbConnection, item, false); } }); sourceInterpreter.OnDataRead += async(table, columns, data, dbDataReader) => { try { StringBuilder sb = new StringBuilder(); (Table Table, List <TableColumn> Columns)targetTableAndColumns = this.GetTargetTableColumns(targetSchemaInfo, this.Target.DbOwner, table, columns); Dictionary <string, object> paramters = targetInterpreter.AppendDataScripts(this.Target.DbInterpreter.Option, sb, targetTableAndColumns.Table, targetTableAndColumns.Columns, new Dictionary <long, List <Dictionary <string, object> > >() { { 1, data } }); try { script = sb.ToString(); sb.Clear(); } catch (OutOfMemoryException e) { sb.Clear(); } if (!this.Option.SplitScriptsToExecute) { if (this.Option.BulkCopy && targetInterpreter.SupportBulkCopy) { if (async) { await targetInterpreter.BulkCopyAsync(dbConnection, dbDataReader, table.Name); } else { targetInterpreter.BulkCopy(dbConnection, dbDataReader, table.Name); } } else { if (async) { await targetInterpreter.ExecuteNonQueryAsync(dbConnection, script, paramters, false); } else { targetInterpreter.ExecuteNonQuery(dbConnection, script, paramters, false); } } } else { string[] sqls = script.Split(new char[] { this.Option.ScriptSplitChar }, StringSplitOptions.RemoveEmptyEntries); foreach (string sql in sqls) { if (!string.IsNullOrEmpty(sql.Trim())) { if (this.Option.BulkCopy && targetInterpreter.SupportBulkCopy) { if (async) { await targetInterpreter.BulkCopyAsync(dbConnection, dbDataReader, table.Name); } else { targetInterpreter.BulkCopy(dbConnection, dbDataReader, table.Name); } } else { if (async) { await targetInterpreter.ExecuteNonQueryAsync(dbConnection, sql, paramters, false); } else { targetInterpreter.ExecuteNonQuery(dbConnection, sql, paramters, false); } } } } } targetInterpreter.FeedbackInfo($"End write data to table {table.Name}, handled rows count:{data.Count}."); } catch (Exception ex) { ConnectionInfo sourceConnectionInfo = sourceInterpreter.ConnectionInfo; ConnectionInfo targetConnectionInfo = targetInterpreter.ConnectionInfo; throw new TableDataTransferException(ex) { SourceServer = sourceConnectionInfo.Server, SourceDatabase = sourceConnectionInfo.Database, SourceTableName = table.Name, TargetServer = targetConnectionInfo.Server, TargetDatabase = targetConnectionInfo.Database, TargetTableName = table.Name }; } }; if (async) { await sourceInterpreter.GenerateDataScriptsAsync(sourceSchemaInfo); } else { sourceInterpreter.GenerateDataScripts(sourceSchemaInfo); } identityTableColumns.ForEach(item => { if (targetInterpreter.DatabaseType == DatabaseType.SqlServer) { targetInterpreter.SetIdentityEnabled(dbConnection, item, true); } }); } } }