public virtual Lite <DisconnectedImportEntity> BeginImportDatabase(DisconnectedMachineEntity machine, Stream file = null) { Lite <DisconnectedImportEntity> import = new DisconnectedImportEntity { Machine = machine.ToLite(), Copies = uploadTables.Select(t => new DisconnectedImportTableEmbedded { Type = t.Type.ToTypeEntity().ToLite(), DisableForeignKeys = t.Strategy.DisableForeignKeys.Value, }).ToMList() }.Save().ToLite(); if (file != null) { using (FileStream fs = File.OpenWrite(BackupNetworkFileName(machine, import))) { file.CopyTo(fs); file.Close(); } } var threadContext = Statics.ExportThreadContext(); var cancelationSource = new CancellationTokenSource(); var user = UserEntity.Current; var token = cancelationSource.Token; var task = Task.Factory.StartNew(() => { lock (SyncLock) using (UserHolder.UserSession(user)) { OnStartImporting(machine); DisconnectedMachineEntity.Current = machine.ToLite(); try { if (file != null) { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.RestoreDatabase, s => l).Execute())) { DropDatabaseIfExists(machine); RestoreDatabase(machine, import); } } string connectionString = GetImportConnectionString(machine); var newDatabase = new SqlConnector(connectionString, Schema.Current, DynamicQueryManager.Current, ((SqlConnector)Connector.Current).Version); using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.SynchronizeSchema, s => l).Execute())) using (Connector.Override(newDatabase)) using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true })) using (ExecutionMode.DisableCache()) { var script = Administrator.TotalSynchronizeScript(interactive: false, schemaOnly: true); if (script != null) { string fileName = BackupNetworkFileName(machine, import) + ".sql"; script.Save(fileName); throw new InvalidOperationException("The schema has changed since the last export. A schema sync script has been saved on: {0}".FormatWith(fileName)); } } try { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.DisableForeignKeys, s => l).Execute())) foreach (var item in uploadTables.Where(u => u.Strategy.DisableForeignKeys.Value)) { DisableForeignKeys(item.Table); } foreach (var tuple in uploadTables) { ImportResult result = null; using (token.MeasureTime(l => { if (result != null) { import.MListElementsLite(_ => _.Copies).Where(mle => mle.Element.Type.RefersTo(tuple.Type.ToTypeEntity())).UnsafeUpdateMList() .Set(mle => mle.Element.CopyTable, mle => l) .Set(mle => mle.Element.DisableForeignKeys, mle => tuple.Strategy.DisableForeignKeys.Value) .Set(mle => mle.Element.InsertedRows, mle => result.Inserted) .Set(mle => mle.Element.UpdatedRows, mle => result.Updated) .Execute(); } })) { result = tuple.Strategy.Importer.Import(machine, tuple.Table, tuple.Strategy, newDatabase); } } using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.Unlock, s => l).Execute())) UnlockTables(machine.ToLite()); } finally { using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.EnableForeignKeys, s => l).Execute())) foreach (var item in uploadTables.Where(u => u.Strategy.DisableForeignKeys.Value)) { EnableForeignKeys(item.Table); } } using (token.MeasureTime(l => import.InDB().UnsafeUpdate().Set(s => s.DropDatabase, s => l).Execute())) DropDatabase(newDatabase); token.ThrowIfCancellationRequested(); import.InDB().UnsafeUpdate() .Set(s => s.State, s => DisconnectedImportState.Completed) .Set(s => s.Total, s => s.CalculateTotal()) .Execute(); machine.InDB().UnsafeUpdate() .Set(m => m.State, m => file == null ? DisconnectedMachineState.Fixed : DisconnectedMachineState.Connected) .Execute(); } catch (Exception e) { var ex = e.LogException(); import.InDB().UnsafeUpdate() .Set(m => m.Exception, m => ex.ToLite()) .Set(m => m.State, m => DisconnectedImportState.Error) .Execute(); machine.InDB().UnsafeUpdate() .Set(m => m.State, m => DisconnectedMachineState.Faulted) .Execute(); OnImportingError(machine, import, e); } finally { runningImports.Remove(import); DisconnectedMachineEntity.Current = null; OnEndImporting(); } } }); runningImports.Add(import, new RunningImports { Task = task, CancelationSource = cancelationSource }); return(import); }