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); }