示例#1
0
        /// <summary>
        /// Creates new <see cref="Structure"/> of the specified type filled with provided data.
        /// </summary>
        /// <param name="structureType">The type of structure to create. Must be descendant of the <see cref="Structure"/> type.</param>
        /// <param name="structureData">The structure data tuple.</param>
        /// <returns>Created structure.</returns>
        public Structure CreateStructure(Type structureType, Tuple structureData)
        {
            using (Session.OpenSystemLogicOnlyRegion()) {
                ArgumentValidator.EnsureArgumentNotNull(structureType, "structureType");
                if (!WellKnownOrmTypes.Structure.IsAssignableFrom(structureType))
                {
                    throw new InvalidOperationException(
                              string.Format(Strings.TypeXIsNotAnYDescendant, structureType, WellKnownOrmTypes.Structure));
                }

                return(Activator.CreateStructure(Session, structureType, structureData));
            }
        }
示例#2
0
        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;
            }
        }