Esempio n. 1
0
        protected void WriteRUI(IRelationUpdateItem rui, IWriter writer, IncrementalMergeState state)
        {
            if (rui == null)
            {
                return;
            }
            IObjRef[] addedORIs   = rui.AddedORIs;
            IObjRef[] removedORIs = rui.RemovedORIs;

            if (addedORIs != null)
            {
                writer.WriteStartElement(rui.MemberName);
                writer.WriteAttribute("add", addedORIs.Length);
                writer.WriteStartElementEnd();
                WriteObjRefs(addedORIs, writer, state);
                writer.WriteCloseElement(rui.MemberName);
            }
            if (removedORIs != null)
            {
                writer.WriteStartElement(rui.MemberName);
                writer.WriteAttribute("remove", removedORIs.Length);
                writer.WriteStartElementEnd();
                WriteObjRefs(removedORIs, writer, state);
                writer.WriteCloseElement(rui.MemberName);
            }
        }
Esempio n. 2
0
        protected void WriteObjRefs(IObjRef[] objRefs, IWriter writer, IncrementalMergeState incrementalState)
        {
            IConversionHelper conversionHelper = ConversionHelper;

            IObjRef[] clone = (IObjRef[])objRefs.Clone();
            Array.Sort(clone, incrementalState.objRefComparator);
            foreach (IObjRef item in clone)
            {
                writer.WriteStartElement("Entity");
                StateEntry stateEntry = incrementalState.objRefToStateMap.Get(item);
                if (stateEntry != null)
                {
                    writer.WriteAttribute("idx", stateEntry.index);
                    writer.WriteEndElement();
                    continue;
                }
                IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(item.RealType);
                writer.WriteAttribute("type", metaData.EntityType.FullName);
                PrimitiveMember idMember = metaData.GetIdMemberByIdIndex(item.IdNameIndex);
                writer.WriteAttribute(idMember.Name, conversionHelper.ConvertValueToType <String>(item.Id));
                if (item.Version != null)
                {
                    writer.WriteAttribute("version", conversionHelper.ConvertValueToType <String>(item.Version));
                }
                writer.WriteEndElement();
            }
        }
Esempio n. 3
0
 protected void WriteRUIs(IRelationUpdateItem[] fullRUIs, IWriter writer, IncrementalMergeState state)
 {
     if (fullRUIs == null)
     {
         return;
     }
     foreach (IRelationUpdateItem rui in fullRUIs)
     {
         WriteRUI(rui, writer, state);
     }
 }
Esempio n. 4
0
        protected void WriteCUDResult(ICUDResult cudResult, IWriter writer, IncrementalMergeState state)
        {
            IList <IChangeContainer> allChanges = cudResult.AllChanges;

            List <CreateContainer> creates = new List <CreateContainer>();
            List <UpdateContainer> updates = new List <UpdateContainer>();
            List <DeleteContainer> deletes = new List <DeleteContainer>();

            for (int a = allChanges.Count; a-- > 0;)
            {
                IChangeContainer changeContainer = allChanges[a];
                if (changeContainer is CreateContainer)
                {
                    creates.Add((CreateContainer)changeContainer);
                }
                else if (changeContainer is UpdateContainer)
                {
                    updates.Add((UpdateContainer)changeContainer);
                }
                else
                {
                    deletes.Add((DeleteContainer)changeContainer);
                }
            }
            creates.Sort(createContainerComparator);
            updates.Sort(updateContainerComparator);
            deletes.Sort(deleteContainerComparator);

            writer.WriteStartElement("CUDResult");
            writer.WriteAttribute("size", allChanges.Count);
            writer.WriteAttribute("creates", creates.Count);
            writer.WriteAttribute("updates", updates.Count);
            writer.WriteAttribute("deletes", deletes.Count);
            writer.WriteStartElementEnd();

            WriteChangeContainers(creates, writer, "Creates", state);
            WriteChangeContainers(updates, writer, "Updates", state);
            WriteChangeContainers(deletes, writer, "Deletes", state);

            writer.WriteCloseElement("CUDResult");
        }
Esempio n. 5
0
        protected ICUDResult WhatIfMerged(ICUDResult cudResult, IMethodDescription methodDescription, List <MergeOperation> mergeOperationSequence,
                                          IncrementalMergeState incrementalState)
        {
            IList <MergeOperation> lastMergeOperationSequence;

            while (true)
            {
                IMap <Type, IList <IChangeContainer> > sortedChanges = BucketSortChanges(cudResult.AllChanges);
                lastMergeOperationSequence = CreateMergeOperationSequence(sortedChanges);

                ParamHolder <bool>     hasAtLeastOneImplicitChange = new ParamHolder <bool>(false);
                IList <MergeOperation> fLastMergeOperationSequence = lastMergeOperationSequence;
                cudResult = CacheContext.ExecuteWithCache(incrementalState.GetStateCache(), delegate(ICUDResult cudResult2)
                {
                    for (int a = 0, size = fLastMergeOperationSequence.Count; a < size; a++)
                    {
                        MergeOperation mergeOperation = fLastMergeOperationSequence[a];
                        IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension;

                        ICUDResult explAndImplCudResult = mergeServiceExtension.EvaluateImplicitChanges(cudResult2, incrementalState);
                        cudResult2 = MergeCudResult(cudResult2, explAndImplCudResult, mergeServiceExtension, hasAtLeastOneImplicitChange,
                                                    incrementalState);
                    }
                    return(cudResult2);
                }, cudResult);
                foreach (IMergeListener mergeListener in mergeListeners.GetExtensions())
                {
                    ICUDResult explAndImplCudResult = mergeListener.PreMerge(cudResult, incrementalState.GetStateCache());
                    cudResult = MergeCudResult(cudResult, explAndImplCudResult, mergeListener, hasAtLeastOneImplicitChange, incrementalState);
                }
                if (!hasAtLeastOneImplicitChange.Value)
                {
                    break;
                }
            }
            mergeOperationSequence.AddRange(lastMergeOperationSequence);
            return(cudResult);
        }
Esempio n. 6
0
        protected ICUDResult MergeCudResult(ICUDResult cudResult, ICUDResult explAndImplCudResult, Object implyingHandle,
                                            ParamHolder <Boolean> hasAtLeastOneImplicitChange, IncrementalMergeState state)
        {
            if (explAndImplCudResult == null || Object.ReferenceEquals(cudResult, explAndImplCudResult))
            {
                return(cudResult);
            }
            ICUDResult diffCUDResult = CudResultComparer.DiffCUDResult(cudResult, explAndImplCudResult);

            if (diffCUDResult == null)
            {
                return(cudResult);
            }
            hasAtLeastOneImplicitChange.Value = true;
            CudResultApplier.ApplyCUDResultOnEntitiesOfCache(diffCUDResult, false, state);
            if (Log.DebugEnabled)
            {
                Object currHandle = implyingHandle;
                if (currHandle is IProxyTargetAccessor)
                {
                    IInterceptor interceptor = ((IProxyTargetAccessor)currHandle).GetInterceptors()[0];
                    while (interceptor is CascadedInterceptor)
                    {
                        Object target = ((CascadedInterceptor)interceptor).Target;
                        if (target is IInterceptor)
                        {
                            interceptor = ((IInterceptor)target);
                            continue;
                        }
                        currHandle = target;
                        break;
                    }
                }
                if (currHandle == null)
                {
                    currHandle = implyingHandle;
                }
                if (CudResultPrinter != null)
                {
                    Log.Debug("Incremental merge [" + RuntimeHelpers.GetHashCode(state) + "] (" + currHandle.GetType().Name + "):\n"
                              + CudResultPrinter.PrintCUDResult(diffCUDResult, state));
                }
                else
                {
                    Log.Debug("Incremental merge [" + RuntimeHelpers.GetHashCode(state) + "]  (" + currHandle.GetType().Name + "). No Details printable");
                }
            }
            return(explAndImplCudResult);
        }
Esempio n. 7
0
        protected IOriCollection Intern(ICUDResult cudResult, IMethodDescription methodDescription, IList <MergeOperation> mergeOperationSequence,
                                        IncrementalMergeState state)
        {
            IList <IChangeContainer> allChanges   = cudResult.AllChanges;
            IList <Object>           originalRefs = cudResult.GetOriginalRefs();
            IdentityHashMap <IChangeContainer, int> changeToChangeIndexDict = new IdentityHashMap <IChangeContainer, int>();

            for (int a = allChanges.Count; a-- > 0;)
            {
                changeToChangeIndexDict.Put(allChanges[a], a);
            }
            IObjRef[] objRefs      = new IObjRef[allChanges.Count];
            long[]    allChangedOn = new long[allChanges.Count];
            String[]  allChangedBy = new String[allChanges.Count];

            CHashSet <long>   changedOnSet = new CHashSet <long>();
            CHashSet <String> changedBySet = new CHashSet <String>();

            for (int a = 0, size = mergeOperationSequence.Count; a < size; a++)
            {
                MergeOperation         mergeOperation        = mergeOperationSequence[a];
                IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension;

                IList <IChangeContainer> changesForMergeService = mergeOperation.ChangeContainer;
                ICUDResult msCudResult = BuildCUDResult(changesForMergeService, changeToChangeIndexDict, originalRefs);

                IOriCollection msOriCollection = mergeServiceExtension.Merge(msCudResult, methodDescription);

                MergeController.ApplyChangesToOriginals(msCudResult, msOriCollection, state.GetStateCache());

                IList <IObjRef> allChangeORIs = msOriCollection.AllChangeORIs;

                long?  msDefaultChangedOn = msOriCollection.ChangedOn;
                String msDefaultChangedBy = msOriCollection.ChangedBy;

                long[]   msAllChangedOn = msOriCollection.AllChangedOn;
                String[] msAllChangedBy = msOriCollection.AllChangedBy;
                for (int b = changesForMergeService.Count; b-- > 0;)
                {
                    int index = changeToChangeIndexDict.Get(changesForMergeService[b]);
                    objRefs[index] = allChangeORIs[b];

                    if (msAllChangedOn != null)
                    {
                        long msChangedOn = msAllChangedOn[b];
                        allChangedOn[index] = msChangedOn;
                        changedOnSet.Add(msChangedOn);
                    }
                    else
                    {
                        allChangedOn[index] = msDefaultChangedOn.Value;
                    }
                    if (msAllChangedBy != null)
                    {
                        String msChangedBy = msAllChangedBy[b];
                        allChangedBy[index] = msChangedBy;
                        changedBySet.Add(msChangedBy);
                    }
                    else
                    {
                        allChangedBy[index] = msDefaultChangedBy;
                    }
                }
                if (msDefaultChangedOn != null)
                {
                    changedOnSet.Add(msDefaultChangedOn.Value);
                }
                if (msDefaultChangedBy != null)
                {
                    changedBySet.Add(msDefaultChangedBy);
                }
            }
            OriCollection oriCollection = new OriCollection();

            oriCollection.AllChangeORIs = new List <IObjRef>(objRefs);

            if (changedBySet.Count == 1)
            {
                Iterator <String> iter = changedBySet.Iterator();
                iter.MoveNext();
                oriCollection.ChangedBy = iter.Current;
            }
            else
            {
                oriCollection.AllChangedBy = allChangedBy;
            }
            if (changedOnSet.Count == 1)
            {
                Iterator <long> iter = changedOnSet.Iterator();
                iter.MoveNext();
                oriCollection.ChangedOn = iter.Current;
            }
            else
            {
                oriCollection.AllChangedOn = allChangedOn;
            }
            foreach (IMergeListener mergeListener in mergeListeners.GetExtensions())
            {
                mergeListener.PostMerge(cudResult, objRefs);
            }
            if (originalRefs != null)
            {
                // Set each original ref to null in order to suppress a post-processing in a potentially calling IMergeProcess
                for (int a = originalRefs.Count; a-- > 0;)
                {
                    originalRefs[a] = null;
                }
            }
            // TODO DCE must be fired HERE <---
            return(oriCollection);
        }
Esempio n. 8
0
        protected IOriCollection MergeIntern(ICUDResult cudResultOriginal, IMethodDescription methodDescription)
        {
            IResultingBackgroundWorkerDelegate <IOriCollection> runnable = new IResultingBackgroundWorkerDelegate <IOriCollection>(delegate()
            {
                IDisposableCache childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false,
                                                                            "MergeServiceRegistry.STATE");
                try
                {
                    IncrementalMergeState state = null;
                    ICUDResult cudResultOfCache;
                    if (MergeProcess.IsAddNewlyPersistedEntities() || (Log.DebugEnabled && CudResultPrinter != null))
                    {
                        childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false,
                                                                   "MergeServiceRegistry.STATE");
                        state            = (IncrementalMergeState)CudResultApplier.AcquireNewState(childCache);
                        cudResultOfCache = CudResultApplier.ApplyCUDResultOnEntitiesOfCache(cudResultOriginal, true, state);
                    }
                    else
                    {
                        cudResultOfCache = cudResultOriginal;
                    }
                    if (Log.DebugEnabled)
                    {
                        if (CudResultPrinter != null)
                        {
                            Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]:\n" + CudResultPrinter.PrintCUDResult(cudResultOfCache, state));
                        }
                        else
                        {
                            Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]. No Details available");
                        }
                    }
                    List <MergeOperation> mergeOperationSequence = new List <MergeOperation>();
                    ICUDResult extendedCudResult = WhatIfMerged(cudResultOfCache, methodDescription, mergeOperationSequence, state);

                    if (Log.DebugEnabled)
                    {
                        Log.Debug("Merge finished [" + RuntimeHelpers.GetHashCode(state) + "]");
                    }
                    if (MergeSecurityManager != null)
                    {
                        SecurityActive.ExecuteWithSecurityDirective(SecurityDirective.ENABLE_ENTITY_CHECK, delegate()
                        {
                            MergeSecurityManager.CheckMergeAccess(extendedCudResult, methodDescription);
                        });
                    }
                    List <Object> originalRefsOfCache  = new List <Object>(cudResultOfCache.GetOriginalRefs());
                    List <Object> originalRefsExtended = new List <Object>(extendedCudResult.GetOriginalRefs());
                    IOriCollection oriCollExtended     = Intern(extendedCudResult, methodDescription, mergeOperationSequence, state);

                    IList <IChangeContainer> allChangesOriginal = cudResultOriginal.AllChanges;
                    IList <IObjRef> allChangedObjRefsExtended   = oriCollExtended.AllChangeORIs;
                    IObjRef[] allChangedObjRefsResult           = new IObjRef[allChangesOriginal.Count];

                    IdentityHashMap <Object, int?> originalRefOfCacheToIndexMap = new IdentityHashMap <Object, int?>();
                    for (int a = originalRefsOfCache.Count; a-- > 0;)
                    {
                        originalRefOfCacheToIndexMap.Put(originalRefsOfCache[a], a);
                    }
                    for (int a = originalRefsExtended.Count; a-- > 0;)
                    {
                        int?indexOfCache = originalRefOfCacheToIndexMap.Get(originalRefsExtended[a]);
                        if (indexOfCache == null)
                        {
                            // this is a change implied by a rule or an persistence-implicit change
                            // we do not know about it in the outer original CUDResult
                            continue;
                        }
                        IObjRef objRefExtended = allChangedObjRefsExtended[a];
                        IObjRef objRefOriginal = allChangesOriginal[indexOfCache.Value].Reference;
                        if (objRefExtended == null)
                        {
                            // entity has been deleted
                            objRefOriginal.Id      = null;
                            objRefOriginal.Version = null;
                        }
                        else
                        {
                            objRefOriginal.Id      = objRefExtended.Id;
                            objRefOriginal.Version = objRefExtended.Version;
                        }
                        if (objRefOriginal is IDirectObjRef)
                        {
                            ((IDirectObjRef)objRefOriginal).Direct = null;
                        }
                        allChangedObjRefsResult[indexOfCache.Value] = objRefOriginal;
                    }
                    OriCollection oriCollection = new OriCollection(new List <IObjRef>(allChangedObjRefsResult));

                    return(oriCollection);
                }
                finally
                {
                    childCache.Dispose();
                }
            });

            if (SecurityActive == null || !SecurityActive.FilterActivated)
            {
                return(runnable());
            }
            else
            {
                return(SecurityActive.ExecuteWithoutFiltering(runnable));
            }
        }
Esempio n. 9
0
        protected void WriteChangeContainer(IChangeContainer changeContainer, IWriter writer, IncrementalMergeState incrementalState)
        {
            IObjRef objRef = changeContainer.Reference;

            writer.WriteStartElement("Entity");
            writer.WriteAttribute("type", objRef.RealType.FullName);
            writer.WriteAttribute("id", ConversionHelper.ConvertValueToType <String>(objRef.Id));
            if (objRef.Version != null)
            {
                writer.WriteAttribute("version", ConversionHelper.ConvertValueToType <String>(objRef.Version));
            }
            StateEntry stateEntry = incrementalState.objRefToStateMap.Get(objRef);

            if (stateEntry == null)
            {
                throw new Exception();
            }
            writer.WriteAttribute("idx", stateEntry.index);
            if (changeContainer is DeleteContainer)
            {
                writer.WriteEndElement();
                return;
            }
            ICreateOrUpdateContainer createOrUpdate = (ICreateOrUpdateContainer)changeContainer;

            WritePUIs(createOrUpdate.GetFullPUIs(), writer);
            WriteRUIs(createOrUpdate.GetFullRUIs(), writer, incrementalState);
            writer.WriteCloseElement("Entity");
        }
Esempio n. 10
0
 protected void WriteChangeContainers <V>(IList <V> changes, IWriter writer, String elementName, IncrementalMergeState state) where V : IChangeContainer
 {
     if (changes.Count == 0)
     {
         return;
     }
     writer.WriteStartElement(elementName);
     writer.WriteStartElementEnd();
     for (int a = 0, size = changes.Count; a < size; a++)
     {
         WriteChangeContainer(changes[a], writer, state);
     }
     writer.WriteCloseElement(elementName);
 }
Esempio n. 11
0
 public CloneState(IdentityHashMap <IObjRef, StateEntry> newObjRefToStateEntryMap,
                   IncrementalMergeState incrementalState)
 {
     this.newObjRefToStateEntryMap = newObjRefToStateEntryMap;
     this.incrementalState         = incrementalState;
 }
Esempio n. 12
0
        protected ICUDResult ApplyIntern(ICUDResult cudResult, bool checkBaseState, IncrementalMergeState incrementalState)
        {
            ICache stateCache = incrementalState.GetStateCache();
            IList <IChangeContainer> allChanges   = cudResult.AllChanges;
            IList <Object>           originalRefs = cudResult.GetOriginalRefs();
            IList <Object>           allObjects   = GetAllExistingObjectsFromCache(stateCache, allChanges);
            List <Object>            hardRefs     = new List <Object>();

            hardRefs.Add(allObjects); // add list as item intended. adding each item of the source is NOT needed

            List <IObjRef> toFetchFromCache             = new List <IObjRef>();
            List <DirectValueHolderRef>      toPrefetch = new List <DirectValueHolderRef>();
            List <IBackgroundWorkerDelegate> runnables  = new List <IBackgroundWorkerDelegate>();

            IEntityFactory entityFactory = this.EntityFactory;

            IdentityHashMap <IObjRef, StateEntry> newObjRefToStateEntryMap        = new IdentityHashMap <IObjRef, StateEntry>();
            IdentityHashMap <IChangeContainer, IChangeContainer> alreadyClonedMap = new IdentityHashMap <IChangeContainer, IChangeContainer>();

            List <IChangeContainer> newAllChanges = new List <IChangeContainer>(allChanges.Count);

            for (int a = 0, size = allChanges.Count; a < size; a++)
            {
                IChangeContainer changeContainer = allChanges[a];
                Object           originalEntity  = originalRefs[a];

                StateEntry stateEntry = incrementalState.entityToStateMap.Get(originalEntity);

                IChangeContainer newChangeContainer;
                if (changeContainer is CreateContainer)
                {
                    newChangeContainer = new CreateContainer();
                }
                else if (changeContainer is UpdateContainer)
                {
                    newChangeContainer = new UpdateContainer();
                }
                else
                {
                    newChangeContainer = new DeleteContainer();
                }
                newAllChanges.Add(newChangeContainer);
                alreadyClonedMap.Put(changeContainer, newChangeContainer);

                if (!(changeContainer is CreateContainer))
                {
                    Object stateCacheEntity2 = allObjects[a];
                    stateEntry = incrementalState.entityToStateMap.Get(stateCacheEntity2);
                    if (stateEntry == null)
                    {
                        stateEntry = new StateEntry(stateCacheEntity2, changeContainer.Reference, incrementalState.entityToStateMap.Count + 1);

                        incrementalState.entityToStateMap.Put(stateCacheEntity2, stateEntry);
                        incrementalState.objRefToStateMap.Put(stateEntry.objRef, stateEntry);
                    }
                    // delete & update do not need further handling
                    continue;
                }
                Type realType = changeContainer.Reference.RealType;

                Object stateCacheEntity;
                if (stateEntry == null)
                {
                    stateCacheEntity = entityFactory.CreateEntity(realType);

                    DirectObjRef directObjRef = new DirectObjRef(realType, stateCacheEntity);
                    directObjRef.CreateContainerIndex = a;

                    stateEntry = new StateEntry(stateCacheEntity, directObjRef, incrementalState.entityToStateMap.Count + 1);

                    incrementalState.entityToStateMap.Put(stateCacheEntity, stateEntry);
                    incrementalState.objRefToStateMap.Put(stateEntry.objRef, stateEntry);
                    newObjRefToStateEntryMap.Put(changeContainer.Reference, stateEntry);
                }
                else
                {
                    stateCacheEntity = stateEntry.entity;
                }
                allObjects[a] = stateCacheEntity;
            }
            cloneStateTL.Value = new CloneState(newObjRefToStateEntryMap, incrementalState);
            try
            {
                for (int a = allChanges.Count; a-- > 0;)
                {
                    IChangeContainer changeContainer = allChanges[a];
                    IObjRefContainer entity          = (IObjRefContainer)allObjects[a];

                    changeContainer = FillClonedChangeContainer(changeContainer, alreadyClonedMap);

                    IPrimitiveUpdateItem[] puis;
                    IRelationUpdateItem[]  ruis;
                    if (changeContainer is CreateContainer)
                    {
                        CreateContainer createContainer = (CreateContainer)changeContainer;
                        puis = createContainer.Primitives;
                        ruis = createContainer.Relations;
                    }
                    else if (changeContainer is UpdateContainer)
                    {
                        UpdateContainer updateContainer = (UpdateContainer)changeContainer;
                        puis = updateContainer.Primitives;
                        ruis = updateContainer.Relations;
                    }
                    else
                    {
                        ((IDataObject)entity).ToBeDeleted = true;
                        continue;
                    }
                    IEntityMetaData metaData = ((IEntityMetaDataHolder)entity).Get__EntityMetaData();
                    ApplyPrimitiveUpdateItems(entity, puis, metaData);

                    if (ruis != null)
                    {
                        bool isUpdate = changeContainer is UpdateContainer;
                        foreach (IRelationUpdateItem rui in ruis)
                        {
                            ApplyRelationUpdateItem(entity, rui, isUpdate, metaData, toPrefetch, toFetchFromCache, checkBaseState, runnables);
                        }
                    }
                }
                while (toPrefetch.Count > 0 || toFetchFromCache.Count > 0 || runnables.Count > 0)
                {
                    if (toPrefetch.Count > 0)
                    {
                        PrefetchHelper.Prefetch(toPrefetch);
                        toPrefetch.Clear();
                    }
                    if (toFetchFromCache.Count > 0)
                    {
                        IList <Object> fetchedObjects = stateCache.GetObjects(toFetchFromCache, CacheDirective.None);
                        hardRefs.Add(fetchedObjects); // add list as item intended. adding each item of the source is NOT needed
                        toFetchFromCache.Clear();
                    }
                    IBackgroundWorkerDelegate[] runnableArray = runnables.ToArray();
                    runnables.Clear();
                    foreach (IBackgroundWorkerDelegate runnable in runnableArray)
                    {
                        runnable();
                    }
                }
                List <Object> newObjects = new List <Object>(allObjects.Count);
                List <DirectValueHolderRef> changedRelationRefs = new List <DirectValueHolderRef>();
                for (int a = allObjects.Count; a-- > 0;)
                {
                    IChangeContainer      newChange = newAllChanges[a];
                    IRelationUpdateItem[] ruis      = null;
                    Object entity = allObjects[a];
                    if (newChange is CreateContainer)
                    {
                        newObjects.Add(entity);
                        ruis = ((CreateContainer)newChange).Relations;
                    }
                    else if (newChange is UpdateContainer)
                    {
                        ruis = ((UpdateContainer)newChange).Relations;
                    }
                    if (ruis == null)
                    {
                        continue;
                    }
                    IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(entity.GetType());
                    foreach (IRelationUpdateItem rui in ruis)
                    {
                        Member member = metaData.GetMemberByName(rui.MemberName);
                        changedRelationRefs.Add(new DirectValueHolderRef((IObjRefContainer)entity, (RelationMember)member));
                    }
                }
                if (newObjects.Count > 0)
                {
                    ((IWritableCache)stateCache).Put(newObjects);
                }
                if (changedRelationRefs.Count > 0)
                {
                    PrefetchHelper.Prefetch(changedRelationRefs);
                }
                return(new CUDResult(newAllChanges, allObjects));
            }
            finally
            {
                cloneStateTL.Value = null;
            }
        }