Esempio n. 1
0
        protected void ApplyRelationUpdateItems(IObjRefContainer entity, IRelationUpdateItem[] ruis, bool isUpdate, IEntityMetaData metadata, IReader reader)
        {
            List <Object> toPrefetch = new List <Object>();

            RelationMember[] relationMembers = metadata.RelationMembers;
            foreach (IRelationUpdateItem rui in ruis)
            {
                String memberName    = rui.MemberName;
                int    relationIndex = metadata.GetIndexByRelationName(memberName);
                if (ValueHolderState.INIT == entity.Get__State(relationIndex))
                {
                    throw new Exception("ValueHolder already initialized for property '" + memberName + "'");
                }

                IObjRef[] existingORIs = entity.Get__ObjRefs(relationIndex);
                IObjRef[] addedORIs    = rui.AddedORIs;
                IObjRef[] removedORIs  = rui.RemovedORIs;

                IObjRef[] newORIs;
                if (existingORIs.Length == 0)
                {
                    if (removedORIs != null && addedORIs.Length > 0)
                    {
                        throw new ArgumentException("Removing from empty member");
                    }
                    newORIs = addedORIs != null && addedORIs.Length > 0 ? addedORIs : ObjRef.EMPTY_ARRAY;
                }
                else
                {
                    // Set to efficiently remove entries
                    LinkedHashSet <IObjRef> existingORIsSet = new LinkedHashSet <IObjRef>(existingORIs);
                    if (removedORIs != null && removedORIs.Length > 0)
                    {
                        foreach (IObjRef removedORI in removedORIs)
                        {
                            if (!existingORIsSet.Remove(removedORI))
                            {
                                throw OptimisticLockUtil.ThrowModified(OriHelper.EntityToObjRef(entity), null, entity);
                            }
                        }
                    }
                    if (addedORIs != null && addedORIs.Length > 0)
                    {
                        foreach (IObjRef addedORI in addedORIs)
                        {
                            if (!existingORIsSet.Add(addedORI))
                            {
                                throw OptimisticLockUtil.ThrowModified(OriHelper.EntityToObjRef(entity), null, entity);
                            }
                        }
                    }
                    if (existingORIsSet.Count == 0)
                    {
                        newORIs = ObjRef.EMPTY_ARRAY;
                    }
                    else
                    {
                        newORIs = existingORIsSet.ToArray();
                    }
                }

                RelationMember member = relationMembers[relationIndex];
                if (isUpdate)
                {
                    entity.Set__ObjRefs(relationIndex, newORIs);
                    if (!entity.Is__Initialized(relationIndex))
                    {
                        DirectValueHolderRef dvhr = new DirectValueHolderRef(entity, member);
                        toPrefetch.Add(dvhr);
                    }
                }
                else
                {
                    BuildSetterCommands(entity, newORIs, member, reader);
                }
            }
            if (toPrefetch.Count > 0)
            {
                IObjectFuture  objectFuture = new PrefetchFuture(toPrefetch);
                IObjectCommand command      = CommandBuilder.Build(reader.CommandTypeRegistry, objectFuture, null);
                reader.AddObjectCommand(command);
            }
        }
Esempio n. 2
0
        protected void ApplyRelationUpdateItem(IObjRefContainer entity, IRelationUpdateItem rui, bool isUpdate,
                                               IEntityMetaData metaData, IList <DirectValueHolderRef> toPrefetch, List <IObjRef> toFetchFromCache, bool checkBaseState,
                                               IList <IBackgroundWorkerDelegate> runnables)
        {
            IObjRefHelper  objRefHelper   = this.ObjRefHelper;
            String         memberName     = rui.MemberName;
            int            relationIndex  = metaData.GetIndexByRelationName(memberName);
            RelationMember relationMember = metaData.RelationMembers[relationIndex];

            IObjRef[] existingORIs;
            if (entity.Is__Initialized(relationIndex))
            {
                existingORIs = ListUtil.ToArray(ObjRefHelper.ExtractObjRefList(relationMember.GetValue(entity), null));
            }
            else
            {
                existingORIs = entity.Get__ObjRefs(relationIndex);
                if (existingORIs == null)
                {
                    toPrefetch.Add(new DirectValueHolderRef(entity, relationMember, true));
                    runnables.Add(new IBackgroundWorkerDelegate(delegate()
                    {
                        ApplyRelationUpdateItem(entity, rui, isUpdate, metaData, toPrefetch, toFetchFromCache, checkBaseState, runnables);
                    }));
                    return;
                }
            }
            IObjRef[] addedORIs   = rui.AddedORIs;
            IObjRef[] removedORIs = rui.RemovedORIs;

            IObjRef[] newORIs;
            if (existingORIs.Length == 0)
            {
                if (checkBaseState && removedORIs != null)
                {
                    throw new Exception("Removing from empty member");
                }
                newORIs = addedORIs != null ? (IObjRef[])addedORIs.Clone() : ObjRef.EMPTY_ARRAY;
                for (int a = newORIs.Length; a-- > 0;)
                {
                    newORIs[a] = CloneObjRef(newORIs[a], false);
                }
            }
            else
            {
                // Set to efficiently remove entries
                LinkedHashSet <IObjRef> existingORIsSet = new LinkedHashSet <IObjRef>(existingORIs);
                if (removedORIs != null)
                {
                    foreach (IObjRef removedORI in removedORIs)
                    {
                        IObjRef clonedObjRef = CloneObjRef(removedORI, false);
                        if (existingORIsSet.Remove(clonedObjRef) || !checkBaseState)
                        {
                            continue;
                        }
                        throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity);
                    }
                }
                if (addedORIs != null)
                {
                    foreach (IObjRef addedORI in addedORIs)
                    {
                        IObjRef clonedObjRef = CloneObjRef(addedORI, false);
                        if (existingORIsSet.Add(clonedObjRef) || !checkBaseState)
                        {
                            continue;
                        }
                        throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity);
                    }
                }
                if (existingORIsSet.Count == 0)
                {
                    newORIs = ObjRef.EMPTY_ARRAY;
                }
                else
                {
                    newORIs = existingORIsSet.ToArray();
                }
            }
            if (!entity.Is__Initialized(relationIndex))
            {
                entity.Set__ObjRefs(relationIndex, newORIs);
                return;
            }
            toFetchFromCache.AddRange(newORIs);
            runnables.Add(new IBackgroundWorkerDelegate(delegate()
            {
                ICache stateCache      = cloneStateTL.Value.incrementalState.GetStateCache();
                IList <Object> objects = stateCache.GetObjects(newORIs, CacheDirective.FailEarly);
                Object value;
                if (relationMember.IsToMany)
                {
                    // To-many relation
                    Object coll = ListUtil.CreateObservableCollectionOfType(relationMember.RealType, objects.Count);
                    ListUtil.FillList(coll, objects);
                    value = coll;
                }
                else
                {
                    // To-one relation
                    value = objects.Count > 0 ? objects[0] : null;
                }
                relationMember.SetValue(entity, value);
            }));
        }