Beispiel #1
0
        public virtual void EnsurePropertyIsLoaded(object obj, IPropertyMap propertyMap)
        {
            IObjectManager     om = this.Context.ObjectManager;
            IPersistenceEngine pe = this.Context.PersistenceEngine;
            ObjectStatus       objStatus;
            PropertyStatus     propStatus;

            objStatus = om.GetObjectStatus(obj);
            if (objStatus != ObjectStatus.Deleted)
            {
                if (objStatus == ObjectStatus.NotLoaded)
                {
                    pe.LoadObject(ref obj);
                    if (pe == null)
                    {
                        throw new ObjectNotFoundException("Object not found!");                         // do not localize
                    }
                }
                propStatus = om.GetPropertyStatus(obj, propertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    pe.LoadProperty(obj, propertyMap.Name);
                }
            }
            else
            {
                //We really ought to throw an exception here...
            }
        }
        public void EnsureLoaded()
        {
            if (MuteNotify)
            {
                return;
            }

            IContext       ctx        = interceptable.GetInterceptor().Context;
            IObjectManager om         = ctx.ObjectManager;
            PropertyStatus propStatus = om.GetPropertyStatus(interceptable, propertyName);

            if (propStatus == PropertyStatus.NotLoaded)
            {
                ObjectStatus objStatus = om.GetObjectStatus(interceptable);
                if (!(objStatus == ObjectStatus.UpForCreation))
                {
                    bool stackMute = MuteNotify;
                    MuteNotify = true;

                    ctx.PersistenceEngine.LoadProperty(interceptable, propertyName);

                    MuteNotify = stackMute;
                }
            }
        }
        protected virtual void HandleOneOnePropertySet(object obj, IPropertyMap propertyMap, object value, object oldValue)
        {
            this.Context.LogManager.Info(this, "Managing inverse one-one property relationship synchronization", "Writing to object of type: " + obj.GetType().ToString() + ", Property: " + propertyMap.Name);             // do not localize

            PropertyStatus propStatus;

            IPropertyMap invPropertyMap = propertyMap.GetInversePropertyMap();

            if (invPropertyMap == null)
            {
                return;
            }
            IObjectManager om = this.Context.ObjectManager;

            if (value != null)
            {
                propStatus = om.GetPropertyStatus(value, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    AddAction(InverseActionType.Set, value, invPropertyMap.Name, obj, obj);
                }
                else
                {
                    om.EnsurePropertyIsLoaded(value, invPropertyMap);
                    om.SetPropertyValue(value, invPropertyMap.Name, obj);
                    om.SetNullValueStatus(value, invPropertyMap.Name, false);
                    om.SetUpdatedStatus(value, invPropertyMap.Name, true);
                }
            }

            if (oldValue != null)
            {
                propStatus = om.GetPropertyStatus(value, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    AddAction(InverseActionType.Set, value, invPropertyMap.Name, null, obj);
                }
                else
                {
                    om.EnsurePropertyIsLoaded(oldValue, invPropertyMap);
                    om.SetPropertyValue(oldValue, invPropertyMap.Name, null);
                    om.SetNullValueStatus(oldValue, invPropertyMap.Name, false);
                    om.SetUpdatedStatus(oldValue, invPropertyMap.Name, true);
                }
            }
        }
Beispiel #4
0
        public void ValidateObject(object obj, IList exceptions)
        {
            IObjectManager om       = this.Context.ObjectManager;
            IClassMap      classMap = this.Context.DomainMap.MustGetClassMap(obj.GetType());

            ValidationMode objValidationMode = GetValidationMode(classMap);

            if (objValidationMode != ValidationMode.Off)
            {
                CustomValidateObject(obj, classMap, exceptions);
                ObjectStatus objStatus = om.GetObjectStatus(obj);
                foreach (IPropertyMap propertyMap in classMap.GetAllPropertyMaps())
                {
                    ValidationMode validationMode = GetValidationMode(classMap, propertyMap);

                    if (validationMode != ValidationMode.Off)
                    {
                        PropertyStatus propStatus = om.GetPropertyStatus(obj, propertyMap.Name);

                        if (validationMode == ValidationMode.ValidateAll && objStatus != ObjectStatus.UpForCreation)
                        {
                            this.Context.ObjectManager.EnsurePropertyIsLoaded(obj, propertyMap);
                        }

                        if (objStatus == ObjectStatus.UpForCreation || propStatus != PropertyStatus.NotLoaded)
                        {
                            bool ok = false;
                            if (validationMode == ValidationMode.Default || validationMode == ValidationMode.ValidateLoaded || validationMode == ValidationMode.ValidateAll)
                            {
                                ok = true;
                            }
                            else if (validationMode == ValidationMode.ValidateDirty)
                            {
                                if (propStatus == PropertyStatus.Dirty)
                                {
                                    ok = true;
                                }
                            }

                            if (ok)
                            {
                                DoValidateProperty(obj, propertyMap, exceptions);
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public virtual void InvalidateProperty(object obj, IPropertyMap propertyMap)
        {
            IObjectManager     om = this.Context.ObjectManager;
            IPersistenceEngine pe = this.Context.PersistenceEngine;
            ObjectStatus       objStatus;
            PropertyStatus     propStatus;

            objStatus  = om.GetObjectStatus(obj);
            propStatus = om.GetPropertyStatus(obj, propertyMap.Name);
            if (propStatus == PropertyStatus.NotLoaded)
            {
                RemoveOriginalValues(obj, propertyMap.Name);

                //pe.LoadProperty(obj, propertyMap.Name);
            }
        }
        public void ValidateObject(object obj, IList exceptions)
        {
            IObjectManager om       = this.Context.ObjectManager;
            IClassMap      classMap = this.Context.DomainMap.MustGetClassMap(obj.GetType());

            CustomValidateObject(obj, classMap, exceptions);
            ObjectStatus objStatus = om.GetObjectStatus(obj);

            foreach (IPropertyMap propertyMap in classMap.GetAllPropertyMaps())
            {
                PropertyStatus propStatus = om.GetPropertyStatus(obj, propertyMap.Name);
                if (objStatus == ObjectStatus.UpForCreation || propStatus != PropertyStatus.NotLoaded)
                {
                    DoValidateProperty(obj, propertyMap, exceptions);
                }
            }
        }
        public virtual void InvalidateProperty(object obj, IPropertyMap propertyMap, bool invalidateDirty)
        {
            if (propertyMap.IsIdentity)
            {
                throw new NPersistException("Identity properties can not be invalidated! Property: " + AssemblyManager.GetBaseType(obj).Name + "." + propertyMap.Name, obj, propertyMap.Name);
            }

            IObjectManager     om = this.Context.ObjectManager;
            IPersistenceEngine pe = this.Context.PersistenceEngine;
            PropertyStatus     propStatus;

            propStatus = om.GetPropertyStatus(obj, propertyMap.Name);
            if (!(propStatus == PropertyStatus.Dirty && invalidateDirty == false))
            {
                RemoveOriginalValues(obj, propertyMap.Name);
            }
        }
        protected virtual void HandleOneManyPropertySet(object obj, IPropertyMap propertyMap, object value, object oldValue)
        {
            this.Context.LogManager.Info(this, "Managing inverse one-many property relationship synchronization", "Writing to object of type: " + obj.GetType().ToString() + ", Property: " + propertyMap.Name);             // do not localize

            PropertyStatus propStatus;
            IPropertyMap   invPropertyMap = propertyMap.GetInversePropertyMap();

            if (invPropertyMap == null)
            {
                return;
            }
            IObjectManager     om = this.Context.ObjectManager;
            IList              list;
            IInterceptableList mList;
            bool stackMute = false;

            if (value != null)
            {
                propStatus = om.GetPropertyStatus(value, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    AddAction(InverseActionType.Add, value, invPropertyMap.Name, obj, obj);
                }
                else
                {
                    om.EnsurePropertyIsLoaded(value, invPropertyMap);
                    list  = (IList)om.GetPropertyValue(value, invPropertyMap.Name);
                    mList = list as IInterceptableList;
                    if (mList != null)
                    {
                        stackMute        = mList.MuteNotify;
                        mList.MuteNotify = true;
                    }
                    list.Add(obj);
                    if (mList != null)
                    {
                        mList.MuteNotify = stackMute;
                    }
                    om.SetUpdatedStatus(value, invPropertyMap.Name, true);
                }
            }

            if (oldValue != null)
            {
                propStatus = om.GetPropertyStatus(oldValue, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    AddAction(InverseActionType.Remove, oldValue, invPropertyMap.Name, obj, obj);
                }
                else
                {
                    om.EnsurePropertyIsLoaded(oldValue, invPropertyMap);
                    list  = (IList)om.GetPropertyValue(oldValue, invPropertyMap.Name);
                    mList = list as IInterceptableList;
                    if (mList != null)
                    {
                        stackMute        = mList.MuteNotify;
                        mList.MuteNotify = true;
                    }
                    list.Remove(obj);
                    if (mList != null)
                    {
                        mList.MuteNotify = stackMute;
                    }
                }
            }
        }
        protected virtual void HandleManyManyPropertySet(object obj, IPropertyMap propertyMap, IList newList, IList oldList)
        {
            this.Context.LogManager.Info(this, "Managing inverse many-many property relationship synchronization", "Writing to object of type: " + obj.GetType().ToString() + ", Property: " + propertyMap.Name);             // do not localize

            PropertyStatus propStatus;
            IPropertyMap   invPropertyMap = propertyMap.GetInversePropertyMap();

            if (invPropertyMap == null)
            {
                return;
            }
            ArrayList          added   = GetListDiff(oldList, newList);
            ArrayList          removed = GetListDiff(newList, oldList);
            IObjectManager     om      = this.Context.ObjectManager;
            IList              list;
            IInterceptableList mList;
            bool   stackMute = false;
            object value;

            foreach (object iValue in added)
            {
                value      = iValue;
                propStatus = om.GetPropertyStatus(value, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    value = iValue;
                    AddAction(InverseActionType.Add, value, invPropertyMap.Name, obj, obj);
                }
                else
                {
                    //we still ensure so that the object is also always loaded...
                    om.EnsurePropertyIsLoaded(value, invPropertyMap);
                    list  = (IList)om.GetPropertyValue(value, invPropertyMap.Name);
                    mList = list as IInterceptableList;
                    if (mList != null)
                    {
                        stackMute        = mList.MuteNotify;
                        mList.MuteNotify = true;
                    }
                    list.Add(obj);
                    if (mList != null)
                    {
                        mList.MuteNotify = stackMute;
                    }
                    om.SetUpdatedStatus(value, invPropertyMap.Name, true);
                }
            }
            foreach (object iValue in removed)
            {
                value      = iValue;
                propStatus = om.GetPropertyStatus(value, invPropertyMap.Name);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    value = iValue;
                    AddAction(InverseActionType.Remove, value, invPropertyMap.Name, obj, obj);
                }
                else
                {
                    //we still ensure so that the object is also always loaded...
                    om.EnsurePropertyIsLoaded(value, invPropertyMap);
                    list  = (IList)om.GetPropertyValue(value, invPropertyMap.Name);
                    mList = list as IInterceptableList;
                    if (mList != null)
                    {
                        stackMute        = mList.MuteNotify;
                        mList.MuteNotify = true;
                    }
                    list.Remove(obj);
                    if (mList != null)
                    {
                        mList.MuteNotify = stackMute;
                    }
                    om.SetUpdatedStatus(value, invPropertyMap.Name, true);
                }
            }
        }
        private void RefreshProperty(IObjectManager om, object targetObject, IPropertyMap propertyMap, IPersistenceManager pm, RefreshBehaviorType refreshBehavior, object value, out bool doWrite, out bool doWriteOrg)
        {
            doWrite = false;
            doWriteOrg = false;
            PropertyStatus propStatus = om.GetPropertyStatus(targetObject, propertyMap.Name);
            IClassMap classMap = this.Context.DomainMap.MustGetClassMap(targetObject.GetType());

            RefreshBehaviorType useRefreshBehavior = pm.GetRefreshBehavior(refreshBehavior, classMap, propertyMap);

            if (useRefreshBehavior == RefreshBehaviorType.OverwriteNotLoaded || useRefreshBehavior == RefreshBehaviorType.DefaultBehavior)
            {
                //Overwrite both value and original far all unloaded properties
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    doWrite = true;
                    doWriteOrg = true;
                }
            }
            else if (useRefreshBehavior == RefreshBehaviorType.OverwriteLoaded)
            {
                //Overwrite original for all properties
                //Overwrite value for all clean or unloaded properties (but not for dirty or deleted properties)
                doWriteOrg = true;
                if (propStatus == PropertyStatus.Clean || propStatus == PropertyStatus.NotLoaded)
                    doWrite = true;
            }
            else if (useRefreshBehavior == RefreshBehaviorType.ThrowConcurrencyException)
            {
                //Overwrite original for all properties unless the old originial value and the fresh value from the
                //database mismatch, in that case raise an exception
                //Overwrite value for all clean or unloaded properties (but not for dirty or deleted properties)
                if (propStatus == PropertyStatus.Clean || propStatus == PropertyStatus.NotLoaded || propStatus == PropertyStatus.Dirty)
                {
                    if (!(propStatus == PropertyStatus.NotLoaded))
                    {
                        object testValue = om.GetOriginalPropertyValue(targetObject,propertyMap.Name);
                        object testValue2 = value;
                        if (DBNull.Value.Equals(testValue)) { testValue = null; }
                        if (DBNull.Value.Equals(testValue2)) { testValue2 = null; }
                        if (testValue2 != testValue)
                        {
                            string cachedValue = "null";
                            string freshValue = "null";
                            try
                            {
                                if (testValue != null)
                                    cachedValue = testValue.ToString() ;
                            }
                            catch { ; }
                            try
                            {
                                if (value != null)
                                    freshValue = value.ToString() ;
                            }
                            catch { ; }
                            throw new RefreshException("A refresh concurrency exception occurred when refreshing a cached object of type " + targetObject.GetType().ToString() + " with fresh data from the data source. The data source row has been modified since the last time this version of the object was loaded, specifically the value for property " + propertyMap.Name + ". (this exception occurs because ThrowConcurrencyExceptions refresh behavior was selected). Cashed value: " + cachedValue + ", Fresh value: " + freshValue, cachedValue, freshValue, targetObject, propertyMap.Name); // do not localize
                        }
                    }
                    if (!(propStatus == PropertyStatus.Dirty))
                        doWrite = true;
                }
            }
            else if (useRefreshBehavior == RefreshBehaviorType.OverwriteDirty)
            {
                //Overwrite original for all properties
                //Overwrite value for all clean, unloaded or dirty properties (but not for deleted properties)
                doWriteOrg = true;
                if (!(propStatus == PropertyStatus.Deleted))
                    doWrite = true;
            }
            else
            {
                throw new NPersistException("Unknown object refresh behavior specified!"); // do not localize
            }
        }
        private void RefreshProperty(IObjectManager om, object targetObject, IPropertyMap propertyMap, IPersistenceManager pm, RefreshBehaviorType refreshBehavior, object value, out bool doWrite, out bool doWriteOrg)
        {
            doWrite    = false;
            doWriteOrg = false;
            PropertyStatus propStatus = om.GetPropertyStatus(targetObject, propertyMap.Name);
            IClassMap      classMap   = this.Context.DomainMap.MustGetClassMap(targetObject.GetType());

            RefreshBehaviorType useRefreshBehavior = pm.GetRefreshBehavior(refreshBehavior, classMap, propertyMap);

            if (useRefreshBehavior == RefreshBehaviorType.OverwriteNotLoaded || useRefreshBehavior == RefreshBehaviorType.DefaultBehavior)
            {
                //Overwrite both value and original far all unloaded properties
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    doWrite    = true;
                    doWriteOrg = true;
                }
            }
            else if (useRefreshBehavior == RefreshBehaviorType.OverwriteLoaded)
            {
                //Overwrite original for all properties
                //Overwrite value for all clean or unloaded properties (but not for dirty or deleted properties)
                doWriteOrg = true;
                if (propStatus == PropertyStatus.Clean || propStatus == PropertyStatus.NotLoaded)
                {
                    doWrite = true;
                }
            }
            else if (useRefreshBehavior == RefreshBehaviorType.ThrowConcurrencyException)
            {
                //Overwrite original for all properties unless the old originial value and the fresh value from the
                //database mismatch, in that case raise an exception
                //Overwrite value for all clean or unloaded properties (but not for dirty or deleted properties)
                if (propStatus == PropertyStatus.Clean || propStatus == PropertyStatus.NotLoaded || propStatus == PropertyStatus.Dirty)
                {
                    if (!(propStatus == PropertyStatus.NotLoaded))
                    {
                        object testValue  = om.GetOriginalPropertyValue(targetObject, propertyMap.Name);
                        object testValue2 = value;
                        if (DBNull.Value.Equals(testValue))
                        {
                            testValue = null;
                        }
                        if (DBNull.Value.Equals(testValue2))
                        {
                            testValue2 = null;
                        }
                        if (testValue2 != testValue)
                        {
                            string cachedValue = "null";
                            string freshValue  = "null";
                            try
                            {
                                if (testValue != null)
                                {
                                    cachedValue = testValue.ToString();
                                }
                            }
                            catch {; }
                            try
                            {
                                if (value != null)
                                {
                                    freshValue = value.ToString();
                                }
                            }
                            catch {; }
                            throw new RefreshException("A refresh concurrency exception occurred when refreshing a cached object of type " + targetObject.GetType().ToString() + " with fresh data from the data source. The data source row has been modified since the last time this version of the object was loaded, specifically the value for property " + propertyMap.Name + ". (this exception occurs because ThrowConcurrencyExceptions refresh behavior was selected). Cashed value: " + cachedValue + ", Fresh value: " + freshValue, cachedValue, freshValue, targetObject, propertyMap.Name);                             // do not localize
                        }
                    }
                    if (!(propStatus == PropertyStatus.Dirty))
                    {
                        doWrite = true;
                    }
                }
            }
            else if (useRefreshBehavior == RefreshBehaviorType.OverwriteDirty)
            {
                //Overwrite original for all properties
                //Overwrite value for all clean, unloaded or dirty properties (but not for deleted properties)
                doWriteOrg = true;
                if (!(propStatus == PropertyStatus.Deleted))
                {
                    doWrite = true;
                }
            }
            else
            {
                throw new NPersistException("Unknown object refresh behavior specified!");                 // do not localize
            }
        }
Beispiel #12
0
        //[DebuggerStepThrough()]
        protected virtual void DoNotifyPropertySet(object obj, string propertyName, ref object value, object oldValue, bool hasOldValue, ref bool cancel)
        {
            IContext                ctx = this.Context;
            IObjectManager          om  = ctx.ObjectManager;
            IPersistenceEngine      pe  = ctx.PersistenceEngine;
            PropertyCancelEventArgs e;

            if (hasOldValue)
            {
                e = new PropertyCancelEventArgs(obj, propertyName, value, oldValue, this.Context.ObjectManager.GetNullValueStatus(obj, propertyName));
            }
            else
            {
                e = new PropertyCancelEventArgs(obj, propertyName, value, this.Context.ObjectManager.GetPropertyValue(obj, propertyName), this.Context.ObjectManager.GetNullValueStatus(obj, propertyName));
            }
            this.Context.EventManager.OnWritingProperty(this, e);
            if (e.Cancel)
            {
                cancel = true;
                return;
            }
            value = e.NewValue;
            IClassMap    classMap = ctx.DomainMap.MustGetClassMap(obj.GetType());
            IPropertyMap propertyMap;
            string       prevId;
            string       newId;

            propertyMap = classMap.MustGetPropertyMap(propertyName);

            if (propertyMap.ReferenceType != ReferenceType.None && value != null)
            {
                if (propertyMap.ReferenceType == ReferenceType.OneToMany || propertyMap.ReferenceType == ReferenceType.OneToOne)
                {
                    //parent object
                    IInterceptable ivalue = value as IInterceptable;
                    if (ivalue == null)
                    {
                        throw new NPersistException(string.Format("Object is not a NPersist managed object, do not use 'new' on Entities. (Property='{0}', Owner={1})", propertyName, obj));
                    }
                    else
                    {
                        if (ivalue.GetInterceptor().Context != this.Context)
                        {
                            throw new NPersistException(string.Format("Object does not belong to the same context object as the property owner. (Property='{0}', Owner={1})", propertyName, obj));
                        }
                        ObjectStatus valueObjectStatus = om.GetObjectStatus(value);
                        if (valueObjectStatus == ObjectStatus.UpForDeletion || valueObjectStatus == ObjectStatus.Deleted)
                        {
                            throw new DeletedObjectException(string.Format("Object has been deleted. (Object={0})", value), value);
                        }
                    }
                }
                else if (propertyMap.ReferenceType == ReferenceType.ManyToOne || propertyMap.ReferenceType == ReferenceType.ManyToMany)
                {
                    IInterceptableList ivalue = value as IInterceptableList;
                    if (ivalue == null)
                    {
                        throw new NPersistException(string.Format("List is not a NPersist managed list, do not use 'new' to initialize lists, NPersist does this for you. (Property='{0}', Owner={1})", propertyName, obj));
                    }
                    else if (ivalue.Interceptable.GetInterceptor().Context != this.Context)
                    {
                        throw new NPersistException(string.Format("List does not belong to the same context object as the property owner. (Property='{0}', Owner={1})", propertyName, obj));
                    }
                }
            }

            if (propertyMap.IsReadOnly)
            {
                //Let read-only inverse properties through
                if (!(propertyMap.ReferenceType != ReferenceType.None && propertyMap.Inverse.Length > 0 && propertyMap.NoInverseManagement == false))
                {
                    //Special - if someone forgot to make their ManyOne read-only,
                    //why bug them about it? (so don't add an "else" with an exception...)
                    if (propertyMap.ReferenceType != ReferenceType.ManyToOne)
                    {
                        throw new ReadOnlyException("Property '" + classMap.Name + "." + propertyName + "' is read-only!");                         // do not localize
                    }
                }
            }
            PropertyStatus propStatus        = PropertyStatus.Clean;
            ObjectStatus   objStatus         = om.GetObjectStatus(obj);
            bool           hasPropertyStatus = false;

            if (objStatus == ObjectStatus.Deleted)
            {
                throw new DeletedObjectException("The object has been deleted!", obj, propertyName);                 // do not localize
            }
            else if (objStatus == ObjectStatus.UpForDeletion)
            {
                throw new DeletedObjectException("The object has been registered as up for deletion!", obj, propertyName);                 // do not localize
            }

            this.Context.ObjectCloner.EnsureIsClonedIfEditing(obj);

            if (objStatus == ObjectStatus.UpForCreation)
            {
            }
            else if (objStatus == ObjectStatus.Clean)
            {
                propStatus = om.GetPropertyStatus(obj, propertyName);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    pe.LoadProperty(obj, propertyName);
                }
                if (!(hasOldValue))
                {
                    if (!(om.ComparePropertyValues(obj, propertyName, value, om.GetPropertyValue(obj, propertyName))))
                    {
                        this.Context.UnitOfWork.RegisterDirty(obj);
                    }
                }
            }
            else if (objStatus == ObjectStatus.NotLoaded)
            {
                propertyMap = this.Context.DomainMap.MustGetClassMap(obj.GetType()).MustGetPropertyMap(propertyName);
                if (!(propertyMap.IsIdentity))
                {
                    propStatus        = this.Context.ObjectManager.GetPropertyStatus(obj, propertyName);
                    hasPropertyStatus = true;
                    //it would be sweet to be able to determine beforehand if this property would be part of the span
                    //that is loaded with LoadObject and only call LoadObject if that is the case....
                    if (propStatus == PropertyStatus.NotLoaded)
                    {
                        hasPropertyStatus = false;
                        //this.Context.PersistenceEngine.LoadObject(ref obj);
                        this.Context.IdentityMap.LoadObject(ref obj, true);
                        if (obj == null)
                        {
                            throw new ObjectNotFoundException("Object not found!");                             // do not localize
                        }
                    }
                    if (!hasPropertyStatus)
                    {
                        propStatus = om.GetPropertyStatus(obj, propertyName);
                    }

                    if (propStatus == PropertyStatus.NotLoaded)
                    {
                        pe.LoadProperty(obj, propertyName);
                    }
                }

                if (!(hasOldValue))
                {
                    if (!(om.ComparePropertyValues(obj, propertyName, value, om.GetPropertyValue(obj, propertyName))))
                    {
                        this.Context.UnitOfWork.RegisterDirty(obj);
                    }
                }
            }
            else if (objStatus == ObjectStatus.Dirty)
            {
                propStatus = om.GetPropertyStatus(obj, propertyName);
                if (propStatus == PropertyStatus.NotLoaded)
                {
                    pe.LoadProperty(obj, propertyName);
                }
            }
            if (propertyMap.IsIdentity)
            {
                prevId = om.GetObjectIdentity(obj);
                newId  = om.GetObjectIdentity(obj, propertyMap, value);
                if (prevId != newId)
                {
                    ctx.IdentityMap.UpdateIdentity(obj, prevId, newId);
                }
            }
            om.SetNullValueStatus(obj, propertyName, false);
            om.SetUpdatedStatus(obj, propertyName, true);
            if (hasOldValue)
            {
                ctx.InverseManager.NotifyPropertySet(obj, propertyName, value, oldValue);
                ctx.UnitOfWork.RegisterDirty(obj);
            }
            else
            {
                ctx.InverseManager.NotifyPropertySet(obj, propertyName, value);
            }
        }
        protected virtual Hashtable GetConcernedTableMaps(object obj, int exceptionLimit, Hashtable tableMaps, IDomainMap dm, IObjectManager om, bool update)
        {
            if (obj == null)
                return null;
            ITableMap tableMap = null;
            IClassMap classMap = dm.MustGetClassMap(obj.GetType());
            if (classMap.Table != "")
            {
                tableMap = classMap.GetTableMap();
                if (tableMap != null)
                    tableMaps[tableMap] = tableMap;
                foreach (IPropertyMap propertyMap in classMap.GetAllPropertyMaps())
                {
                    if (propertyMap.Table != "")
                    {
                        if (!(propertyMap.IsSlave || propertyMap.IsReadOnly))
                        {
                            bool ok = true;
                            if (update)
                            {
                                PropertyStatus propStatus = om.GetPropertyStatus(obj, propertyMap.Name);
                                if (propStatus != PropertyStatus.Dirty)
                                    ok = false;
                            }
                            if (ok)
                            {
                                tableMap = propertyMap.GetTableMap();
                                if (tableMap != null)
                                    tableMaps[tableMap] = tableMap;
                            }
                        }
                    }
                }
            }

            return tableMaps;
        }