internal (JObject typeChanges, int typeChangesCount, long maxTimeStamp, List <SyncLog.SyncLogData> logChanges) GetTypeChanges(long?lastSync, Type syncType, string synchronizationId, Dictionary <string, object> customInfo, List <object> appliedIds) { if (string.IsNullOrEmpty(synchronizationId)) { throw new NullReferenceException(nameof(synchronizationId)); } if (lastSync == null) { lastSync = GetMinValueTicks(); } if (customInfo == null) { customInfo = new Dictionary <string, object>(); } long maxTimeStamp = GetMinValueTicks(); List <SyncLog.SyncLogData> logChanges = new List <SyncLog.SyncLogData>(); SyncConfiguration.SchemaInfo schemaInfo = GetSchemaInfo(SyncConfiguration, syncType); JObject typeChanges = null; JArray datas = new JArray(); OperationType operationType = OperationType.GetChanges; object transaction = StartTransaction(syncType, operationType, synchronizationId, customInfo); try { IQueryable queryable = InvokeGetQueryable(syncType, transaction, operationType, synchronizationId, customInfo); if (appliedIds == null || appliedIds.Count == 0) { queryable = queryable.Where($"{schemaInfo.PropertyInfoLastUpdated.Name} > @0 || ({schemaInfo.PropertyInfoDeleted.Name} != null && {schemaInfo.PropertyInfoDeleted.Name} > @1)", lastSync.Value, lastSync); } else { Type typeId = Type.GetType(schemaInfo.PropertyInfoId.PropertyType, true); MethodInfo miCast = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(typeId); object appliedIdsTypeId = miCast.Invoke(appliedIds, new object[] { appliedIds }); queryable = queryable.Where($"({schemaInfo.PropertyInfoLastUpdated.Name} > @0 || ({schemaInfo.PropertyInfoDeleted.Name} != null && {schemaInfo.PropertyInfoDeleted.Name} > @1)) && !(@2.Contains({schemaInfo.PropertyInfoId.Name}))", lastSync.Value, lastSync, appliedIdsTypeId); } queryable = queryable.OrderBy($"{schemaInfo.PropertyInfoDeleted.Name}, {schemaInfo.PropertyInfoLastUpdated.Name}"); List <dynamic> dynamicDatas = queryable.ToDynamicList(); if (dynamicDatas.Count > 0) { typeChanges = new JObject(); typeChanges[nameof(syncType)] = syncType.Name; typeChanges[nameof(schemaInfo)] = schemaInfo.ToJObject(); foreach (dynamic dynamicData in dynamicDatas) { JObject jObjectData = InvokeSerializeDataToJson(syncType, dynamicData, schemaInfo, transaction, operationType, synchronizationId, customInfo); datas.Add(jObjectData); long lastUpdated = jObjectData[schemaInfo.PropertyInfoLastUpdated.Name].Value <long>(); long?deleted = jObjectData[schemaInfo.PropertyInfoDeleted.Name].Value <long?>(); if (lastUpdated > maxTimeStamp) { maxTimeStamp = lastUpdated; } if (deleted.HasValue && deleted.Value > maxTimeStamp) { maxTimeStamp = deleted.Value; } logChanges.Add(SyncLog.SyncLogData.FromJObject(jObjectData, syncType, schemaInfo)); } typeChanges[nameof(datas)] = datas; } CommitTransaction(syncType, transaction, operationType, synchronizationId, customInfo); } catch (Exception) { RollbackTransaction(syncType, transaction, operationType, synchronizationId, customInfo); throw; } finally { EndTransaction(syncType, transaction, operationType, synchronizationId, customInfo); } return(typeChanges, datas.Count, maxTimeStamp, logChanges); }
internal (JObject typeChanges, int typeChangesCount, List <SyncLog.SyncLogData> logChanges) GetTypeChangesByKnowledge(Type syncType, string localDatabaseInstanceId, List <KnowledgeInfo> remoteKnowledgeInfos, string synchronizationId, Dictionary <string, object> customInfo) { if (string.IsNullOrEmpty(synchronizationId)) { throw new NullReferenceException(nameof(synchronizationId)); } if (customInfo == null) { customInfo = new Dictionary <string, object>(); } List <SyncLog.SyncLogData> logChanges = new List <SyncLog.SyncLogData>(); SyncConfiguration.SchemaInfo schemaInfo = GetSchemaInfo(SyncConfiguration, syncType); JObject typeChanges = null; JArray datas = new JArray(); OperationType operationType = OperationType.GetChanges; object transaction = StartTransaction(syncType, operationType, synchronizationId, customInfo); try { IQueryable queryable = InvokeGetQueryable(syncType, transaction, operationType, synchronizationId, customInfo); string predicate = ""; string predicateUnknown = ""; for (int i = 0; i < remoteKnowledgeInfos.Count; i++) { KnowledgeInfo info = remoteKnowledgeInfos[i]; string knownDatabaseInstanceId = null; if (info.DatabaseInstanceId == localDatabaseInstanceId) { knownDatabaseInstanceId = "null"; } else { knownDatabaseInstanceId = $"\"{info.DatabaseInstanceId}\""; } if (!string.IsNullOrEmpty(predicate)) { predicate += " || "; } predicate += "("; predicate += $"{schemaInfo.PropertyInfoDatabaseInstanceId.Name} = {knownDatabaseInstanceId} "; predicate += $" && {schemaInfo.PropertyInfoLastUpdated.Name} > {info.MaxTimeStamp}"; predicate += ")"; if (!string.IsNullOrEmpty(predicateUnknown)) { predicateUnknown += " && "; } predicateUnknown += $"{schemaInfo.PropertyInfoDatabaseInstanceId.Name} != {knownDatabaseInstanceId}"; } queryable = queryable.Where($"{predicate} || ({predicateUnknown})"); queryable = queryable.OrderBy($"{schemaInfo.PropertyInfoDeleted.Name}, {schemaInfo.PropertyInfoLastUpdated.Name}"); List <dynamic> dynamicDatas = queryable.ToDynamicList(); if (dynamicDatas.Count > 0) { typeChanges = new JObject(); typeChanges[nameof(syncType)] = syncType.Name; typeChanges[nameof(schemaInfo)] = schemaInfo.ToJObject(); foreach (dynamic dynamicData in dynamicDatas) { JObject jObjectData = InvokeSerializeDataToJson(syncType, dynamicData, schemaInfo, transaction, operationType, synchronizationId, customInfo); datas.Add(jObjectData); logChanges.Add(SyncLog.SyncLogData.FromJObject(jObjectData, syncType, schemaInfo)); } typeChanges[nameof(datas)] = datas; } CommitTransaction(syncType, transaction, operationType, synchronizationId, customInfo); } catch (Exception) { RollbackTransaction(syncType, transaction, operationType, synchronizationId, customInfo); throw; } finally { EndTransaction(syncType, transaction, operationType, synchronizationId, customInfo); } return(typeChanges, datas.Count, logChanges); }