Esempio n. 1
0
        protected IList <MergeOperation> CreateMergeOperationSequence(IMap <Type, IList <IChangeContainer> > sortedChanges)
        {
            Type[] entityPersistOrder = EntityMetaDataProvider.GetEntityPersistOrder();
            IList <MergeOperation> mergeOperations = new List <MergeOperation>();

            if (entityPersistOrder != null)
            {
                for (int a = entityPersistOrder.Length; a-- > 0;)
                {
                    Type orderedEntityType           = entityPersistOrder[a];
                    IList <IChangeContainer> changes = sortedChanges.Get(orderedEntityType);
                    if (changes == null)
                    {
                        // No changes of current type found. Nothing to do here
                        continue;
                    }
                    List <IChangeContainer> removes           = new List <IChangeContainer>(changes.Count);
                    List <IChangeContainer> insertsAndUpdates = new List <IChangeContainer>(changes.Count);
                    for (int b = changes.Count; b-- > 0;)
                    {
                        IChangeContainer change = changes[b];
                        if (change is DeleteContainer)
                        {
                            removes.Add(change);
                        }
                        else
                        {
                            insertsAndUpdates.Add(change);
                        }
                    }
                    if (removes.Count == 0)
                    {
                        // Nothing to do. Ordering is not necessary here
                        continue;
                    }
                    if (insertsAndUpdates.Count == 0)
                    {
                        sortedChanges.Remove(orderedEntityType);
                    }
                    else
                    {
                        sortedChanges.Put(orderedEntityType, insertsAndUpdates);
                    }
                    IMergeServiceExtension mergeServiceExtension = GetServiceForType(orderedEntityType);
                    MergeOperation         mergeOperation        = new MergeOperation();
                    mergeOperation.MergeServiceExtension = mergeServiceExtension;
                    mergeOperation.ChangeContainer       = removes;

                    mergeOperations.Add(mergeOperation);
                }

                for (int a = 0, size = entityPersistOrder.Length; a < size; a++)
                {
                    Type orderedEntityType           = entityPersistOrder[a];
                    IList <IChangeContainer> changes = sortedChanges.Get(orderedEntityType);
                    if (changes == null)
                    {
                        // No changes of current type found. Nothing to do here
                        continue;
                    }
                    bool containsNew = false;
                    for (int b = changes.Count; b-- > 0;)
                    {
                        if (changes[b].Reference.Id == null)
                        {
                            containsNew = true;
                            break;
                        }
                    }
                    if (!containsNew)
                    {
                        // Nothing to do. Ordering is not necessary here
                        continue;
                    }
                    // Remove batch of changes where at least 1 new entity occured and
                    // this type of entity has to be inserted in a global order
                    sortedChanges.Remove(orderedEntityType);
                    IMergeServiceExtension mergeServiceExtension = GetServiceForType(orderedEntityType);
                    MergeOperation         mergeOperation        = new MergeOperation();
                    mergeOperation.MergeServiceExtension = mergeServiceExtension;
                    mergeOperation.ChangeContainer       = changes;

                    mergeOperations.Add(mergeOperation);
                }
            }

            // Everything which is left in the sortedChanges map can be merged without global order, so batch together as much as possible
            foreach (Entry <Type, IList <IChangeContainer> > entry in sortedChanges)
            {
                Type type = entry.Key;
                IList <IChangeContainer> unorderedChanges      = entry.Value;
                IMergeServiceExtension   mergeServiceExtension = GetServiceForType(type);

                if (mergeServiceExtension == null)
                {
                    throw new Exception("No extension found to merge entities of type '" + type.FullName + "'");
                }
                bool cont = false;
                foreach (MergeOperation existingMergeOperation in mergeOperations)
                {
                    if (Object.ReferenceEquals(existingMergeOperation.MergeServiceExtension, mergeServiceExtension))
                    {
                        IList <IChangeContainer> orderedChanges = existingMergeOperation.ChangeContainer;
                        for (int b = unorderedChanges.Count; b-- > 0;)
                        {
                            orderedChanges.Add(unorderedChanges[b]);
                        }
                        cont = true;
                        break;
                    }
                }
                if (cont)
                {
                    continue;
                }
                MergeOperation mergeOperation = new MergeOperation();
                mergeOperation.MergeServiceExtension = mergeServiceExtension;
                mergeOperation.ChangeContainer       = unorderedChanges;

                mergeOperations.Add(mergeOperation);
            }
            ;
            return(mergeOperations);
        }