コード例 #1
0
ファイル: Persistent.cs プロジェクト: lanicon/dataobjects-net
        internal void SetFieldValue(FieldInfo field, object value, SyncContext syncContext, RemovalContext removalContext)
        {
            if (field.ReflectedType.IsInterface)
            {
                field = TypeInfo.FieldMap[field];
            }
            SystemSetValueAttempt(field, value);
            var    fieldAccessor = GetFieldAccessor(field);
            object oldValue      = GetFieldValue(field);

            // Handling 'OldValue != NewValue' problem for structures
            var o = oldValue as Structure;

            if (o != null)
            {
                oldValue = Activator.CreateStructure(Session, o.GetType(), o.Tuple.ToRegular());
            }

            try {
                var operations = Session.Operations;
                var scope      = operations.BeginRegistration(Operations.OperationType.System);
                try {
                    var entity = this as Entity;
                    if (entity != null)
                    {
                        if (operations.CanRegisterOperation)
                        {
                            operations.RegisterOperation(new EntityFieldSetOperation(entity.Key, field, value));
                        }
                        var entityValue = value as IEntity;
                        if (entityValue != null)
                        {
                            var valueKey = entityValue.Key;
                            Session.ReferenceFieldsChangesRegistry.Register(entity.Key, valueKey, field);
                        }
                    }
                    else
                    {
                        var persistent   = this;
                        var currentField = field;
                        var structure    = persistent as Structure;
                        while (structure != null && structure.Owner != null)
                        {
                            var pair = new Pair <FieldInfo>(structure.Field, currentField);
                            currentField = structure.Owner.TypeInfo.StructureFieldMapping[pair];
                            persistent   = structure.Owner;
                            structure    = persistent as Structure;
                        }
                        entity = persistent as Entity;
                        if (entity != null)
                        {
                            if (operations.CanRegisterOperation)
                            {
                                operations.RegisterOperation(new EntityFieldSetOperation(entity.Key, currentField, value));
                            }
                            var entityValue = value as IEntity;
                            if (entityValue != null)
                            {
                                var valueKey = entityValue.Key;
                                Session.ReferenceFieldsChangesRegistry.Register(entity.Key, valueKey, field);
                            }
                        }
                    }

                    if (fieldAccessor.AreSameValues(oldValue, value))
                    {
                        operations.NotifyOperationStarting(false);
                        scope.Complete();
                        return;
                    }
                    {
                        SystemBeforeSetValue(field, value);
                        operations.NotifyOperationStarting(false);
                        AssociationInfo association = null;
                        entity = value as Entity ?? oldValue as Entity;
                        if (entity != null)
                        {
                            association = field.GetAssociation(entity.TypeInfo);
                        }
                        if (association != null && association.IsPaired)
                        {
                            Key currentKey   = GetReferenceKey(field);
                            Key newKey       = null;
                            var newReference = (Entity)(object)value;
                            if (newReference != null)
                            {
                                newKey = newReference.Key;
                            }
                            if (currentKey != newKey)
                            {
                                Session.PairSyncManager.ProcessRecursively(syncContext, removalContext,
                                                                           OperationType.Set, association, (Entity)this, newReference, () => {
                                    SystemBeforeTupleChange();
                                    fieldAccessor.SetUntypedValue(this, value);
                                    SystemTupleChange();
                                });
                            }
                        }
                        else
                        {
                            // The method of Equals(object, object) wrapped with in a block 'try catch',
                            // because that for data types NpgsqlPath and NpgsqlPolygon which are defined without an initial value it works incorrectly.
                            bool canBeEqual;
                            try {
                                canBeEqual = Equals(value, oldValue);
                            }
                            catch (Exception) {
                                canBeEqual = false;
                            }
                            if (!canBeEqual || field.IsStructure)
                            {
                                SystemBeforeTupleChange();
                                value = AdjustFieldValue(field, oldValue, value);
                                fieldAccessor.SetUntypedValue(this, value);
                                SystemTupleChange();
                            }
                        }

                        if (removalContext != null)
                        {
                            // Postponing finalizers (events)
                            removalContext.EnqueueFinalizer(() => {
                                try {
                                    try {
                                        SystemSetValue(field, oldValue, value);
                                        SystemSetValueCompleted(field, oldValue, value, null);
                                        scope.Complete();
                                    }
                                    finally {
                                        scope.DisposeSafely();
                                    }
                                }
                                catch (Exception e) {
                                    SystemSetValueCompleted(field, oldValue, value, e);
                                    throw;
                                }
                            });
                            return;
                        }

                        SystemSetValue(field, oldValue, value);
                        SystemSetValueCompleted(field, oldValue, value, null);
                    }
                    scope.Complete();
                }
                finally {
                    if (removalContext == null)
                    {
                        scope.DisposeSafely();
                    }
                }
            }
            catch (Exception e) {
                SystemSetValueCompleted(field, oldValue, value, e);
                throw;
            }
        }
コード例 #2
0
        internal bool Remove(Entity item, SyncContext syncContext, RemovalContext removalContext)
        {
            if (!Contains(item))
            {
                return(false);
            }

            try {
                var operations = Session.Operations;
                var scope      = operations.BeginRegistration(Operations.OperationType.System);
                try {
                    var itemKey = item.Key;
                    if (operations.CanRegisterOperation)
                    {
                        operations.RegisterOperation(new EntitySetItemRemoveOperation(Owner.Key, Field, itemKey));
                    }

                    SystemBeforeRemove(item);

                    int?   index       = null;
                    var    association = Field.GetAssociation(item.TypeInfo);
                    Action finalizer   = () => {
                        var auxiliaryType = association.AuxiliaryType;
                        if (auxiliaryType != null && association.IsMaster)
                        {
                            var combinedTuple = auxilaryTypeKeyTransform.Apply(
                                TupleTransformType.Tuple,
                                Owner.Key.Value,
                                itemKey.Value);

                            var combinedKey = Key.Create(
                                Session.Domain,
                                Session.StorageNodeId,
                                auxiliaryType,
                                TypeReferenceAccuracy.ExactType,
                                combinedTuple);

                            Session.RemoveOrCreateRemovedEntity(auxiliaryType.UnderlyingType, combinedKey, EntityRemoveReason.Association);
                        }

                        var state = State;
                        index = GetItemIndex(state, itemKey);
                        state.Remove(itemKey);
                        Session.EntitySetChangeRegistry.Register(state);
                    };

                    operations.NotifyOperationStarting();
                    if (association.IsPaired)
                    {
                        Session.PairSyncManager.ProcessRecursively(syncContext, removalContext,
                                                                   OperationType.Remove, association, Owner, item, finalizer);
                    }
                    else
                    {
                        finalizer.Invoke();
                    }

                    if (removalContext != null)
                    {
                        // Postponing finalizers (events)
                        removalContext.EnqueueFinalizer(() => {
                            try {
                                try {
                                    index = GetItemIndex(State, itemKey); // Necessary, since index can be already changed
                                    if (!skipOwnerVersionChange)
                                    {
                                        Owner.UpdateVersionInfo(Owner, Field);
                                    }
                                    SystemRemove(item, index);
                                    SystemRemoveCompleted(item, null);
                                    scope.Complete();
                                }
                                finally {
                                    scope.DisposeSafely();
                                }
                            }
                            catch (Exception e) {
                                SystemRemoveCompleted(item, e);
                                throw;
                            }
                        });
                        return(true);
                    }

                    if (!skipOwnerVersionChange)
                    {
                        Owner.UpdateVersionInfo(Owner, Field);
                    }
                    SystemRemove(item, index);
                    SystemRemoveCompleted(item, null);
                    scope.Complete();
                    return(true);
                }
                finally {
                    if (removalContext == null)
                    {
                        scope.DisposeSafely();
                    }
                }
            }
            catch (Exception e) {
                SystemRemoveCompleted(item, e);
                throw;
            }
        }