protected virtual async Task BuildRetrieveDataTask(DtoSyncConfigSyncFromInformation dtoSyncConfigSyncFromInformation, CancellationToken cancellationToken) { if (dtoSyncConfigSyncFromInformation == null) { throw new ArgumentNullException(nameof(dtoSyncConfigSyncFromInformation)); } try { IBoundClient <IDictionary <string, object> > query = (dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSet)(ODataClient); if (dtoSyncConfigSyncFromInformation.MaxVersion == 0) { query = query.Where($"{nameof(ISyncableDto.IsArchived)} eq false"); } else { query = query.Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromInformation.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 DotNetStandard2_0 || UWP using Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); #elif Android || iOS || DotNetStandard2_1 await using Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); #else await using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).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); dtoSyncConfigSyncFromInformation.RecentlyChangedOnlineDtos = ((IEnumerable)(jToken)["value"] !.ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromInformation.DtoType)) !).Cast <ISyncableDto>().ToArray(); } } } } } catch (Exception exp) { dtoSyncConfigSyncFromInformation.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 <DtoSyncConfigSyncFromInformation> dtoSyncConfigSyncFromInformationList = new List <DtoSyncConfigSyncFromInformation>(); int id = 0; 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; DtoSyncConfigSyncFromInformation dtoSyncConfigSyncFromInformation = new DtoSyncConfigSyncFromInformation { Id = id++, DtoSetSyncConfig = fromServerSyncConfig, DtoType = offlineSet.ElementType.GetTypeInfo(), HadOfflineDtoBefore = mostRecentOfflineDto != null, MaxVersion = maxVersion }; IBoundClient <IDictionary <string, object> > query = (dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSet)(ODataClient); if (dtoSyncConfigSyncFromInformation.MaxVersion == 0) { query = query.Where($"{nameof(ISyncableDto.IsArchived)} eq false"); } else { query = query.Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromInformation.MaxVersion}"); } string oDataGetAndVersionFilter = await query .GetCommandTextAsync(cancellationToken) .ConfigureAwait(false); dtoSyncConfigSyncFromInformation.ODataGetUri = $"{ClientAppProfile.HostUri}{ClientAppProfile.ODataRoute}{oDataGetAndVersionFilter}"; dtoSyncConfigSyncFromInformationList.Add(dtoSyncConfigSyncFromInformation); } StringBuilder batchRequests = new StringBuilder(); batchRequests.AppendLine(@" { ""requests"": ["); foreach (DtoSyncConfigSyncFromInformation?dtoSyncConfigSyncFromInformation in dtoSyncConfigSyncFromInformationList) { batchRequests.AppendLine(@$ " {{ " "id" ": " "{dtoSyncConfigSyncFromInformation.Id}" ", " "method" ": " "GET" ", " "url" ": " "{dtoSyncConfigSyncFromInformation.ODataGetUri}" " }}{(dtoSyncConfigSyncFromInformation != dtoSyncConfigSyncFromInformationList.Last() ? ", " : " ")}"); } batchRequests.AppendLine(@" ] }"); using (HttpResponseMessage batchResponbse = await HttpClient.PostAsync($"{ClientAppProfile.ODataRoute}$batch", new StringContent(batchRequests.ToString(), Encoding.UTF8, "application/json"), cancellationToken).ConfigureAwait(false)) { batchResponbse.EnsureSuccessStatusCode(); if (batchResponbse.Content.Headers.ContentType.MediaType != "application/json") { throw new InvalidOperationException($"{batchResponbse.Content.Headers.ContentType.MediaType} content type is not supported."); } #if UWP || DotNetStandard2_0 using (Stream stream = await batchResponbse.Content.ReadAsStreamAsync().ConfigureAwait(false)) #else await using (Stream stream = await batchResponbse.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); foreach (JToken response in jToken["responses"] !) { int responseId = response.Value <int>("id"); DtoSyncConfigSyncFromInformation?dtoSyncConfigSyncFromInformation = dtoSyncConfigSyncFromInformationList.ExtendedSingle($"Getting dtoSyncConfigSyncFromInformation with id {responseId}", item => item.Id == responseId); dtoSyncConfigSyncFromInformation.RecentlyChangedOnlineDtos = ((IEnumerable)response["body"] !["value"] !.ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromInformation.DtoType)) !).Cast <ISyncableDto>().ToArray();