Esempio n. 1
0
        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();
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
0
 protected List <ISyncableDto> CreateSyncableDtoInstancesFromUnTypedODataResponse(DtoSyncConfigSyncFromResults dtoSyncConfigSyncFromResults, List <IDictionary <string, object> > untypedDtos)
 {
     return(dtoSyncConfigSyncFromResults.RecentlyChangedOnlineDtos = untypedDtos
                                                                     .Select(unTypedDto => unTypedDto.ToDto(dtoSyncConfigSyncFromResults.DtoType))
                                                                     .Cast <ISyncableDto>()
                                                                     .ToList());
 }
Esempio n. 5
0
        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);
                }
            }
        }