ApplySnapshotAsync(ScopeInfo clientScopeInfo, BatchInfo serverBatchInfo, long clientTimestamp, long remoteClientTimestamp, CancellationToken cancellationToken = default, IProgress <ProgressArgs> progress = null) { if (!this.StartTime.HasValue) { this.StartTime = DateTime.UtcNow; } if (serverBatchInfo == null || !await serverBatchInfo.HasDataAsync(this)) { return(new DatabaseChangesApplied(), clientScopeInfo); } // Get context or create a new one var ctx = this.GetContext(); ctx.SyncStage = SyncStage.SnapshotApplying; await this.InterceptAsync(new SnapshotApplyingArgs(ctx), cancellationToken).ConfigureAwait(false); var connection = this.Provider.CreateConnection(); this.logger.LogDebug(SyncEventsId.ApplySnapshot, new { connection.Database, ClientTimestamp = clientTimestamp, RemoteClientTimestamp = remoteClientTimestamp }); if (clientScopeInfo.Schema == null) { throw new ArgumentNullException(nameof(clientScopeInfo.Schema)); } // Applying changes and getting the new client scope info var(changesApplied, newClientScopeInfo) = await this.ApplyChangesAsync(clientScopeInfo, clientScopeInfo.Schema, serverBatchInfo, clientTimestamp, remoteClientTimestamp, ConflictResolutionPolicy.ServerWins, cancellationToken, progress); // Because we have initialize everything here (if syncType != Normal) // We don't want to download everything from server, so change syncType to Normal ctx.SyncType = SyncType.Normal; this.logger.LogInformation(SyncEventsId.ApplyChanges, changesApplied); // Progress & Interceptor ctx.SyncStage = SyncStage.SnapshotApplied; var snapshotAppliedArgs = new SnapshotAppliedArgs(ctx); this.ReportProgress(ctx, progress, snapshotAppliedArgs); await this.InterceptAsync(snapshotAppliedArgs, cancellationToken).ConfigureAwait(false); return(changesApplied, newClientScopeInfo); }