protected virtual async Task BuildRetriveDataTask(DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults, CancellationToken cancellationToken) { string oDataGetAndVersionFilter = await(dtoSyncConfigSyncFromResults.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromResults.DtoSetSyncConfig.OnlineDtoSet)(ODataClient).Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromResults.MaxVersion}").GetCommandTextAsync(cancellationToken).ConfigureAwait(false); string oDataUri = $"{ClientAppProfile.ODataRoute}{oDataGetAndVersionFilter}"; HttpResponseMessage response = await HttpClient.GetAsync(oDataUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); if (response.IsSuccessStatusCode == true) { using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { using (StreamReader reader = new StreamReader(stream)) { using (JsonReader jsonReader = new JsonTextReader(reader)) { JToken jToken = await JToken.LoadAsync(jsonReader, new JsonLoadSettings { CommentHandling = CommentHandling.Ignore, LineInfoHandling = LineInfoHandling.Ignore }, cancellationToken).ConfigureAwait(false); dtoSyncConfigSyncFromResults.RecentlyChangedOnlineDtos = ((IEnumerable)(jToken)["value"].ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromResults.DtoType))).Cast <ISyncableDto>().ToArray(); } } } } }
protected virtual async Task BuildRetriveDataTask(DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults, CancellationToken cancellationToken) { if (dtoSyncConfigSyncFromResults == null) { throw new ArgumentNullException(nameof(dtoSyncConfigSyncFromResults)); } try { IBoundClient <IDictionary <string, object> > query = (dtoSyncConfigSyncFromResults.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromResults.DtoSetSyncConfig.OnlineDtoSet)(ODataClient); if (dtoSyncConfigSyncFromResults.MaxVersion == 0) { query = query.Where($"{nameof(ISyncableDto.IsArchived)} eq false"); } else { query = query.Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromResults.MaxVersion}"); } string oDataGetAndVersionFilter = await query .GetCommandTextAsync(cancellationToken) .ConfigureAwait(false); string oDataUri = $"{ClientAppProfile.ODataRoute}{oDataGetAndVersionFilter}"; using (HttpResponseMessage response = await HttpClient.GetAsync(oDataUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)) { response.EnsureSuccessStatusCode(); #if UWP || DotNetStandard2_0 using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) #else await using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) #endif { using (StreamReader reader = new StreamReader(stream)) { using (JsonReader jsonReader = new JsonTextReader(reader)) { JToken jToken = await JToken.LoadAsync(jsonReader, new JsonLoadSettings { CommentHandling = CommentHandling.Ignore, LineInfoHandling = LineInfoHandling.Ignore }, cancellationToken).ConfigureAwait(false); dtoSyncConfigSyncFromResults.RecentlyChangedOnlineDtos = ((IEnumerable)(jToken)["value"] !.ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromResults.DtoType)) !).Cast <ISyncableDto>().ToArray(); } } } } } catch (Exception exp) { dtoSyncConfigSyncFromResults.RecentlyChangedOnlineDtos = Array.Empty <ISyncableDto>(); ExceptionHandler.OnExceptionReceived(exp); } }
public virtual async Task CallSyncFrom(DtoSetSyncConfig[] fromServerDtoSetSyncMaterials, CancellationToken cancellationToken) { if (fromServerDtoSetSyncMaterials == null) { throw new ArgumentNullException(nameof(fromServerDtoSetSyncMaterials)); } if (fromServerDtoSetSyncMaterials.Any()) { await GetMetadataIfNotRetrievedAlready(cancellationToken).ConfigureAwait(false); await using (EfCoreDbContextBase offlineContextForSyncFrom = Container.Resolve <EfCoreDbContextBase>()) { ((IsSyncDbContext)offlineContextForSyncFrom).IsSyncDbContext = true; List <DtoSyncConfigSyncFromResults> recentlyChangedOnlineDtos = new List <DtoSyncConfigSyncFromResults>(); foreach (DtoSetSyncConfig fromServerSyncConfig in fromServerDtoSetSyncMaterials) { IQueryable <ISyncableDto> offlineSet = fromServerSyncConfig.OfflineDtoSet(offlineContextForSyncFrom); var mostRecentOfflineDto = await offlineSet .IgnoreQueryFilters() .AsNoTracking() .Select(e => new { e.Version }) .OrderByDescending(e => e.Version) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); long maxVersion = mostRecentOfflineDto?.Version ?? 0; DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults = new DtoSyncConfigSyncFromResults { DtoSetSyncConfig = fromServerSyncConfig, DtoType = offlineSet.ElementType.GetTypeInfo(), HadOfflineDtoBefore = mostRecentOfflineDto != null, MaxVersion = maxVersion }; dtoSyncConfigSyncFromResults.RetriveDataTask = BuildRetriveDataTask(dtoSyncConfigSyncFromResults, cancellationToken); recentlyChangedOnlineDtos.Add(dtoSyncConfigSyncFromResults); } await Task.WhenAll(recentlyChangedOnlineDtos.Select(r => r.RetriveDataTask)).ConfigureAwait(false); foreach (DtoSyncConfigSyncFromResults result in recentlyChangedOnlineDtos.Where(r => r.RecentlyChangedOnlineDtos.Any())) { if (result.HadOfflineDtoBefore == false) { foreach (ISyncableDto r in result.RecentlyChangedOnlineDtos) { offlineContextForSyncFrom.Add(r).Property("IsSynced").CurrentValue = true; } } else { PropertyInfo[] keyProps = offlineContextForSyncFrom .Model .FindEntityType(result.DtoType) .FindPrimaryKey() .Properties.Select(x => result.DtoType.GetProperty(x.Name)) .ToArray() !; IQueryable <ISyncableDto> offlineSet = result.DtoSetSyncConfig.OfflineDtoSet(offlineContextForSyncFrom); string equivalentOfflineDtosQuery = ""; List <object> equivalentOfflineDtosParams = new List <object>(); int parameterIndex = 0; equivalentOfflineDtosQuery = string.Join(" || ", result.RecentlyChangedOnlineDtos.Select(s => { return($" ( {string.Join(" && ", keyProps.Select(k => { equivalentOfflineDtosParams.Add(k.GetValue(s)!); return $"{k.Name} == @{parameterIndex++}"; }))} )"); })); List <ISyncableDto> equivalentOfflineDtos = await offlineSet .Where(equivalentOfflineDtosQuery, equivalentOfflineDtosParams.ToArray()) .IgnoreQueryFilters() .AsNoTracking() .ToListAsync(cancellationToken) .ConfigureAwait(false); foreach (ISyncableDto recentlyChangedOnlineDto in result.RecentlyChangedOnlineDtos) { bool hasEquivalentInOfflineDb = equivalentOfflineDtos.Any(d => keyProps.All(k => k.GetValue(d) !.Equals(k.GetValue(recentlyChangedOnlineDto)))); if (recentlyChangedOnlineDto.IsArchived == false || hasEquivalentInOfflineDb == true) { if (recentlyChangedOnlineDto.IsArchived == true) { offlineContextForSyncFrom.Remove(recentlyChangedOnlineDto); } else if (hasEquivalentInOfflineDb == true) { offlineContextForSyncFrom.Update(recentlyChangedOnlineDto).Property("IsSynced").CurrentValue = true; } else { offlineContextForSyncFrom.Add(recentlyChangedOnlineDto).Property("IsSynced").CurrentValue = true; } } } } } await offlineContextForSyncFrom.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } } }
protected List <ISyncableDto> CreateSyncableDtoInstancesFromUnTypedODataResponse(DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults, List <IDictionary <string, object> > untypedDtos) { return(dtoSyncConfigSyncFromResults.RecentlyChangedOnlineDtos = untypedDtos .Select(unTypedDto => unTypedDto.ToDto(dtoSyncConfigSyncFromResults.DtoType)) .Cast <ISyncableDto>() .ToList()); }
public virtual async Task CallSyncFrom(DtoSetSyncConfig[] fromServerDtoSetSyncMaterials, CancellationToken cancellationToken) { if (fromServerDtoSetSyncMaterials.Any()) { using (TDbContext offlineContextForSyncFrom = _dbContextProvider()) { ((IsSyncDbContext)offlineContextForSyncFrom).IsSyncDbContext = true; ODataBatch onlineBatchContext = _oDataBatchProvider(); List <DtoSyncConfigSyncFromResults> recentlyChangedOnlineDtos = new List <DtoSyncConfigSyncFromResults>(); foreach (DtoSetSyncConfig fromServerSyncConfig in fromServerDtoSetSyncMaterials) { IQueryable <ISyncableDto> offlineSet = fromServerSyncConfig.OfflineDtoSet(offlineContextForSyncFrom); var mostRecentOfflineDto = await offlineSet .IgnoreQueryFilters() .AsNoTracking() .Select(e => new { e.Version }) .OrderByDescending(e => e.Version) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); long maxVersion = mostRecentOfflineDto?.Version ?? 0; DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults = new DtoSyncConfigSyncFromResults { DtoSetSyncConfig = fromServerSyncConfig, DtoType = offlineSet.ElementType.GetTypeInfo(), HadOfflineDtoBefore = mostRecentOfflineDto != null }; recentlyChangedOnlineDtos.Add(dtoSyncConfigSyncFromResults); onlineBatchContext += async c => CreateSyncableDtoInstancesFromUnTypedODataResponse(dtoSyncConfigSyncFromResults, (await(fromServerSyncConfig.OnlineDtoSetForGet ?? fromServerSyncConfig.OnlineDtoSet)(c).Where($"Version gt {maxVersion}").FindEntriesAsync(cancellationToken).ConfigureAwait(false)).ToList()); } await onlineBatchContext.ExecuteAsync(cancellationToken).ConfigureAwait(false); foreach (DtoSyncConfigSyncFromResults result in recentlyChangedOnlineDtos.Where(r => r.RecentlyChangedOnlineDtos.Any())) { if (result.HadOfflineDtoBefore == false) { foreach (ISyncableDto r in result.RecentlyChangedOnlineDtos) { offlineContextForSyncFrom.Add(r).Property("IsSynced").CurrentValue = true; } } else { PropertyInfo[] keyProps = offlineContextForSyncFrom .Model .FindEntityType(result.DtoType) .FindPrimaryKey() .Properties.Select(x => result.DtoType.GetProperty(x.Name)) .ToArray(); IQueryable <ISyncableDto> offlineSet = result.DtoSetSyncConfig.OfflineDtoSet(offlineContextForSyncFrom); string equivalentOfflineDtosQuery = ""; List <object> equivalentOfflineDtosParams = new List <object>(); int parameterIndex = 0; equivalentOfflineDtosQuery = string.Join(" || ", result.RecentlyChangedOnlineDtos.Select(s => { return($" ( {string.Join(" && ", keyProps.Select(k => { equivalentOfflineDtosParams.Add(k.GetValue(s)); return $"{k.Name} == @{parameterIndex++}"; }))} )"); })); List <ISyncableDto> equivalentOfflineDtos = await offlineSet .Where(equivalentOfflineDtosQuery, equivalentOfflineDtosParams.ToArray()) .IgnoreQueryFilters() .AsNoTracking() .ToListAsync(cancellationToken) .ConfigureAwait(false); foreach (ISyncableDto recentlyChangedOnlineDto in result.RecentlyChangedOnlineDtos) { bool hasEquivalentInOfflineDb = equivalentOfflineDtos.Any(d => keyProps.All(k => k.GetValue(d).Equals(k.GetValue(recentlyChangedOnlineDto)))); if (recentlyChangedOnlineDto.IsArchived == false || hasEquivalentInOfflineDb == true) { if (recentlyChangedOnlineDto.IsArchived == true) { offlineContextForSyncFrom.Remove(recentlyChangedOnlineDto); } else if (hasEquivalentInOfflineDb == true) { offlineContextForSyncFrom.Update(recentlyChangedOnlineDto).Property("IsSynced").CurrentValue = true; } else { offlineContextForSyncFrom.Add(recentlyChangedOnlineDto).Property("IsSynced").CurrentValue = true; } } } } } await offlineContextForSyncFrom.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } } }