public async Task <bool> SynchronizePartial(
            IEnumerable <IIdWithHints <TAtypeEntityId, TAtypeEntityVersion> > aIds,
            IEnumerable <IIdWithHints <TBtypeEntityId, TBtypeEntityVersion> > bIds,
            ISynchronizationLogger logger,
            Func <Task <TContext> > contextFactoryAsync,
            Func <TContext, Task> syncronizationFinishedAsync)
        {
            s_logger.InfoFormat(
                "Entered partial. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'",
                _initialSyncStateCreationStrategy.GetType().Name,
                typeof(TAtypeEntity).Name,
                typeof(TBtypeEntity).Name);

            var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData();

            if (knownEntityRelations == null)
            {
                var synchronizationContext = await contextFactoryAsync();
                await Synchronize(logger, synchronizationContext);
                await syncronizationFinishedAsync(synchronizationContext);

                return(true);
            }

            var requestedAIdsById = aIds.ToDictionary(e => e.Id, _atypeIdComparer);
            var requestedBIdsById = bIds.ToDictionary(e => e.Id, _btypeIdComparer);

            var aIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TAtypeEntityId> >();
            var bIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TBtypeEntityId> >();

            using (var totalProgress = _totalProgressFactory.Create())
            {
                var entityRelationsToUse    = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();
                var entityRelationsNotToUse = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();

                foreach (var entityRelation in knownEntityRelations)
                {
                    var isACausingSync = RemoveAFromRequestedAndCheckIfCausesSync(requestedAIdsById, entityRelation);
                    var isBCausingSync = RemoveBFromRequestedAndCheckIfCausesSync(requestedBIdsById, entityRelation);

                    if (isACausingSync || isBCausingSync)
                    {
                        aIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TAtypeEntityId>(entityRelation.AtypeId, true));
                        bIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TBtypeEntityId>(entityRelation.BtypeId, true));

                        entityRelationsToUse.Add(entityRelation);
                    }
                    else
                    {
                        entityRelationsNotToUse.Add(entityRelation);
                    }
                }

                aIdsWithAwarenessLevel.AddRange(requestedAIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TAtypeEntityId>(kv.Key, false)));
                bIdsWithAwarenessLevel.AddRange(requestedBIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TBtypeEntityId>(kv.Key, false)));

                if (aIdsWithAwarenessLevel.Count == 0 && bIdsWithAwarenessLevel.Count == 0)
                {
                    s_logger.InfoFormat("Exiting partial since there is nothing to synchronize.");
                    return(false);
                }

                using (var interceptor = _synchronizationInterceptorFactory.Create())
                {
                    var synchronizationContext = await contextFactoryAsync();

                    Task <IEnumerable <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > > aVersionsTask;
                    if (aIdsWithAwarenessLevel.Count > 0)
                    {
                        aVersionsTask = _atypeRepository.GetVersions(aIdsWithAwarenessLevel, synchronizationContext, logger.AGetVersionsEntityLogger);
                    }
                    else
                    {
                        aVersionsTask = Task.FromResult <IEnumerable <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > >(new EntityVersion <TAtypeEntityId, TAtypeEntityVersion>[] { });
                    }

                    Task <IEnumerable <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > > bVersionsTask;
                    if (bIdsWithAwarenessLevel.Count > 0)
                    {
                        bVersionsTask = _btypeRepository.GetVersions(bIdsWithAwarenessLevel, synchronizationContext, logger.BGetVersionsEntityLogger);
                    }
                    else
                    {
                        bVersionsTask = Task.FromResult <IEnumerable <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > >(new EntityVersion <TBtypeEntityId, TBtypeEntityVersion>[] { });
                    }

                    var aStates = VersionAwareEntityStateCollection <TAtypeEntityId, TAtypeEntityVersion> .Create(await aVersionsTask, _atypeIdComparer, _atypeVersionComparer);

                    var bStates = VersionAwareEntityStateCollection <TBtypeEntityId, TBtypeEntityVersion> .Create(await bVersionsTask, _btypeIdComparer, _btypeVersionComparer);

                    await Synchronize(
                        totalProgress,
                        entityRelationsToUse,
                        aStates,
                        bStates,
                        logger,
                        synchronizationContext,
                        interceptor,
                        newEntityRelations =>
                    {
                        entityRelationsNotToUse.AddRange(newEntityRelations);
                        _entityRelationDataAccess.SaveEntityRelationData(entityRelationsNotToUse);
                    });
                }
            }

            s_logger.DebugFormat("Exiting.");
            return(true);
        }
예제 #2
0
 public async Task <IEnumerable <EntityVersion <TEntityId, TEntityVersion> > > GetVersions(IEnumerable <IdWithAwarenessLevel <TEntityId> > idsOfEntitiesToQuery, TContext context, IGetVersionsLogger logger)
 {
     return(await Task.Run(() => _decorated.GetVersions(idsOfEntitiesToQuery, context, logger)));
 }