private void ListDirtyProperties(object entity)
        {
            string className = NHibernateProxyHelper.GuessClass(entity).FullName;
            ISessionImplementor sessionImpl = m_Session.GetSessionImplementation();
            IEntityPersister    persister   = sessionImpl.Factory.GetEntityPersister(className);
            EntityEntry         oldEntry    = sessionImpl.PersistenceContext.GetEntry(entity);

            if (oldEntry == null)
            {
                INHibernateProxy proxy = entity as INHibernateProxy;
                object           obj   = proxy != null?sessionImpl.PersistenceContext.Unproxy(proxy) : entity;

                oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
            }

            object[] oldState        = oldEntry.LoadedState;
            object[] currentState    = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
            int[]    dirtyProperties = persister.FindDirty(currentState, oldState, entity, sessionImpl);

            foreach (int index in dirtyProperties)
            {
                string msg = string.Format(
                    "Dirty property {0}.{1} was {2}, is {3}.",
                    className,
                    persister.PropertyNames[index],
                    oldState[index] ?? "null",
                    currentState[index] ?? "null");
                DirtyProps.Add(msg);
            }
        }
示例#2
0
        protected virtual bool HandleInterception(FlushEntityEvent @event)
        {
            ISessionImplementor session   = @event.Session;
            EntityEntry         entry     = @event.EntityEntry;
            IEntityPersister    persister = entry.Persister;
            object entity = @event.Entity;

            //give the Interceptor a chance to modify property values
            object[] values      = @event.PropertyValues;
            bool     intercepted = InvokeInterceptor(session, entity, entry, values, persister);

            //now we might need to recalculate the dirtyProperties array
            if (intercepted && @event.DirtyCheckPossible && [email protected])
            {
                int[] dirtyProperties;
                if (@event.HasDatabaseSnapshot)
                {
                    dirtyProperties = persister.FindModified(@event.DatabaseSnapshot, values, entity, session);
                }
                else
                {
                    dirtyProperties = persister.FindDirty(values, entry.LoadedState, entity, session);
                }
                @event.DirtyProperties = dirtyProperties;
            }

            return(intercepted);
        }
示例#3
0
        public static bool IsDirtyProperty(this ISession session, object entity, string propertyName)
        {
            ISessionImplementor sessionImpl        = session.GetSessionImplementation();
            IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
            EntityEntry         oldEntry           = persistenceContext.GetEntry(entity);

            if ((oldEntry == null) && (entity is INHibernateProxy))
            {
                var    proxy = entity as INHibernateProxy;
                object obj   = sessionImpl.PersistenceContext.Unproxy(proxy);
                oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
            }
            //NOTE: If the entity is declared as immutable LoadedState is null
            if (oldEntry?.LoadedState == null)
            {
                return(false);
            }
            string           className = oldEntry.EntityName;
            IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

            object[] oldState     = oldEntry.LoadedState;
            object[] currentState = persister.GetPropertyValues(entity);
            try
            {
                int[] dirtyProps = persister.FindDirty(currentState, oldState, entity, sessionImpl);
                int   index      = Array.IndexOf(persister.PropertyNames, propertyName);
                bool  isDirty    = dirtyProps != null && (Array.IndexOf(dirtyProps, index) != -1);
                return(isDirty);
            }
            catch (Exception e)
            {
                LogManager.GetLogger(Assembly.GetEntryAssembly(), "NH Extensions").Error("IsDirtyProperty error!", e);
            }
            return(false);
        }
示例#4
0
        public static object GetOriginalEntityProperty(this ISession session, object entity, string propertyName)
        {
            ISessionImplementor sessionImpl        = session.GetSessionImplementation();
            IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
            EntityEntry         oldEntry           = persistenceContext.GetEntry(entity);

            if ((oldEntry == null) && (entity is INHibernateProxy))
            {
                INHibernateProxy proxy = entity as INHibernateProxy;
                object           obj   = sessionImpl.PersistenceContext.Unproxy(proxy);
                oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
            }
            if (oldEntry == null)
            {
                return(null);
            }
            string           className = oldEntry.EntityName;
            IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

            object[] oldState     = oldEntry.LoadedState;
            object[] currentState = persister.GetPropertyValues(entity);
            int[]    dirtyProps   = persister.FindDirty(currentState, oldState, entity, sessionImpl);
            int      index        = Array.IndexOf(persister.PropertyNames, propertyName);
            bool     isDirty      = (dirtyProps != null) && (Array.IndexOf(dirtyProps, index) != -1);

            return(isDirty ? oldState[index] : currentState[index]);
        }
示例#5
0
        /// <summary>
        /// Возвращает индексы измененных свойств.
        /// </summary>
        public static IList <int> GetDirtyProps(this ISession session, object entity)
        {
            EntityEntry oldEntry = GetOldEntry(session, entity);

            ISessionImplementor sessionImpl = session.GetSessionImplementation();
            string           className      = oldEntry.EntityName;
            IEntityPersister persister      = sessionImpl.Factory.GetEntityPersister(className);

            object[] oldState     = oldEntry.LoadedState;
            object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
            int[]    dirtyProps   = persister.FindDirty(currentState, oldState, entity, sessionImpl);

            List <int> dirty = new List <int>();

            for (int i = 0; i < currentState.Length; i++)
            {
                var ipc = currentState[i] as IPersistentCollection;
                if (ipc != null && ipc.IsDirty)
                {
                    dirty.Add(i);
                }
            }

            if (dirtyProps != null)
            {
                dirty.AddRange(dirtyProps);
            }
            return(dirty);
        }
示例#6
0
    private static bool IsDirty(SaveOrUpdateEvent @event)
    {
        IEntityPersister persister = @event.Entry.Persister;

        object[] oldState     = @event.Entry.LoadedState;
        object[] currentState = persister.GetPropertyValues(@event.Entity, @event.Session.EntityMode);
        Int32[]  dirtyProps   = persister.FindDirty(currentState, oldState, @event.Entity, @event.Session);
        return(dirtyProps != null);
    }
示例#7
0
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="form"></param>
        public void Update(TEntity entity, NameValueCollection form)
        {
            if (form == null)
            {//直接更新
                if (entity is Entity)
                {
                    var et = entity as Entity;
                    et.Modifier   = GetUserId();
                    et.ModifyTime = DateTime.Now;
                }
                _session.Update(entity);
            }
            else
            {//只处理form对象中存在的字段,即客户端提交的字段
                var obj        = entity as Entity;
                var entityInDb = _session.Get <TEntity>(obj.GetId());
                if (entityInDb == null)
                {
                    return;
                }
                //UNDONE: 未处理需要真正更新成null的字段
                ISessionImplementor sessionImpl = _session.GetSessionImplementation();
                string           entityName     = typeof(TEntity).FullName;// sessionImpl.PersistenceContext.GetEntry(entityInDb).EntityName;
                IEntityPersister persister      = sessionImpl.Factory.GetEntityPersister(entityName);

                //处理带前缀的字段名
                var submitedKeys = form.AllKeys
                                   .Select(p => (p.IndexOf(".") > 0) ? p.Substring(p.LastIndexOf(".") + 1) : p)
                                   .ToList();

                object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
                object[] oldState     = persister.GetPropertyValues(entityInDb, sessionImpl.EntityMode);

                for (int i = 0; i < currentState.Length; i++)
                {//合并不为空的字段(只更新不为空的字段)
                    if (submitedKeys.Contains(persister.PropertyNames[i]))
                    {
                        oldState[i] = currentState[i];
                    }
                }
                //判断是否有字段被更新
                int[] dirty = persister.FindDirty(oldState, persister.GetPropertyValues(entityInDb, sessionImpl.EntityMode), entityInDb, sessionImpl);
                if (dirty != null && dirty.Length > 0)
                {
                    //设置更新人和更新时间
                    SetState(persister, oldState, "Modifier", GetUserId());
                    SetState(persister, oldState, "ModifyTime", DateTime.Now);
                }
                //给EntityInDb赋新值
                persister.SetPropertyValues(entityInDb, oldState, sessionImpl.EntityMode);

                _session.Update(entityInDb);
            }
        }
示例#8
0
        /// <summary> Perform a dirty check, and attach the results to the event</summary>
        protected virtual void DirtyCheck(FlushEntityEvent @event)
        {
            object entity = @event.Entity;

            object[]            values    = @event.PropertyValues;
            ISessionImplementor session   = @event.Session;
            EntityEntry         entry     = @event.EntityEntry;
            IEntityPersister    persister = entry.Persister;
            object id = entry.Id;

            object[] loadedState = entry.LoadedState;

            int[] dirtyProperties = session.Interceptor.FindDirty(entity, id, values, loadedState, persister.PropertyNames, persister.PropertyTypes);

            @event.DatabaseSnapshot = null;

            bool interceptorHandledDirtyCheck;
            bool cannotDirtyCheck;

            if (dirtyProperties == null)
            {
                // Interceptor returned null, so do the dirtycheck ourself, if possible
                interceptorHandledDirtyCheck = false;

                cannotDirtyCheck = loadedState == null;                 // object loaded by update()
                if (!cannotDirtyCheck)
                {
                    // dirty check against the usual snapshot of the entity
                    dirtyProperties = persister.FindDirty(values, loadedState, entity, session);
                }
                else
                {
                    // dirty check against the database snapshot, if possible/necessary
                    object[] databaseSnapshot = GetDatabaseSnapshot(session, persister, id);
                    if (databaseSnapshot != null)
                    {
                        dirtyProperties         = persister.FindModified(databaseSnapshot, values, entity, session);
                        cannotDirtyCheck        = false;
                        @event.DatabaseSnapshot = databaseSnapshot;
                    }
                }
            }
            else
            {
                // the Interceptor handled the dirty checking
                cannotDirtyCheck             = false;
                interceptorHandledDirtyCheck = true;
            }

            @event.DirtyProperties = dirtyProperties;
            @event.DirtyCheckHandledByInterceptor = interceptorHandledDirtyCheck;
            @event.DirtyCheckPossible             = !cannotDirtyCheck;
        }
        public static Boolean IsDirtyProperty(this ISession session, Object entity, String propertyName)
        {
            EntityEntry      oldEntry;
            IEntityPersister persister = GetEntityPersister(session, entity, out oldEntry);

            Object[] oldState     = oldEntry.LoadedState;
            Object[] currentState = persister.GetPropertyValues(entity, session.GetSessionImplementation().EntityMode);
            Int32[]  dirtyProps   = persister.FindDirty(currentState, oldState, entity, session.GetSessionImplementation());

            Int32   index   = Array.IndexOf(persister.PropertyNames, propertyName);
            Boolean isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;

            return(isDirty);
        }
示例#10
0
        public Boolean IsDirtyEntity(Object entity)
        {
            if (sessao == null)
            {
                throw new ArgumentNullException("session");
            }
            String className = NHibernateProxyHelper.GuessClass(entity).FullName;
            ISessionImplementor sessionImpl = sessao.GetSessionImplementation();
            IEntityPersister    persister   = sessionImpl.Factory.GetEntityPersister(className);
            EntityEntry         oldEntry    = sessionImpl.PersistenceContext.GetEntry(sessionImpl.PersistenceContext.Unproxy(entity));

            Object[] oldState     = oldEntry.LoadedState;
            Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
            Int32[]  dirtyProps   = persister.FindDirty(currentState, oldState, entity, sessionImpl);
            return(dirtyProps != null);
        }
示例#11
0
        public static object GetOriginalEntityProperty(this ISession session, object entity, String propertyName)
        {
            EntityEntry         oldEntry    = GetOldEntry(session, entity);
            ISessionImplementor sessionImpl = session.GetSessionImplementation();
            string           className      = oldEntry.EntityName;
            IEntityPersister persister      = sessionImpl.Factory.GetEntityPersister(className);

            object[] oldState     = oldEntry.LoadedState;
            object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
            int[]    dirtyProps   = persister.FindDirty(currentState, oldState, entity, sessionImpl);
            int      index        = Array.IndexOf(persister.PropertyNames, propertyName);

            bool isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;

            return((isDirty == true) ? oldState[index] : currentState[index]);
        }
        public static Boolean IsDirtyProperty(this ISession session, Object entity, String propertyName)
        {
            ISessionImplementor sessionImpl = session.GetSessionImplementation();

            IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;

            EntityEntry oldEntry = persistenceContext.GetEntry(entity);

            String className = oldEntry.EntityName;

            IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);



            if ((oldEntry == null) && (entity is INHibernateProxy))
            {
                INHibernateProxy proxy = entity as INHibernateProxy;

                Object obj = sessionImpl.PersistenceContext.Unproxy(proxy);

                oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
            }



            Object[] oldState = oldEntry.LoadedState;

            Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);

            Int32[] dirtyProps = persister.FindDirty(currentState, oldState, entity, sessionImpl);

            Int32 index = Array.IndexOf(persister.PropertyNames, propertyName);



            Boolean isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;



            return(isDirty);
        }
示例#13
0
        /// <summary> Perform a dirty check, and attach the results to the event</summary>
        protected virtual void DirtyCheck(FlushEntityEvent @event)
        {
            object entity = @event.Entity;

            object[]            values    = @event.PropertyValues;
            ISessionImplementor session   = @event.Session;
            EntityEntry         entry     = @event.EntityEntry;
            IEntityPersister    persister = entry.Persister;
            object id = entry.Id;

            object[] loadedState = entry.LoadedState;

            int[] dirtyProperties = session.Interceptor.FindDirty(entity, id, values, loadedState, persister.PropertyNames, persister.PropertyTypes);

            @event.DatabaseSnapshot = null;

            bool interceptorHandledDirtyCheck;
            bool cannotDirtyCheck;

            if (dirtyProperties == null)
            {
                // Interceptor returned null, so do the dirtycheck ourself, if possible
                interceptorHandledDirtyCheck = false;

                cannotDirtyCheck = loadedState == null;                 // object loaded by update()
                if (!cannotDirtyCheck)
                {
                    // dirty check against the usual snapshot of the entity
                    dirtyProperties = persister.FindDirty(values, loadedState, entity, session);
                }
                else if (entry.Status == Status.Deleted && [email protected]())
                {
                    // A non-modifiable (e.g., read-only or immutable) entity needs to be have
                    // references to transient entities set to null before being deleted. No other
                    // fields should be updated.
                    if (values != entry.DeletedState)
                    {
                        throw new InvalidOperationException("Entity has status Status.Deleted but values != entry.DeletedState");
                    }
                    // Even if loadedState == null, we can dirty-check by comparing currentState and
                    // entry.getDeletedState() because the only fields to be updated are those that
                    // refer to transient entities that are being set to null.
                    // - currentState contains the entity's current property values.
                    // - entry.getDeletedState() contains the entity's current property values with
                    //   references to transient entities set to null.
                    // - dirtyProperties will only contain properties that refer to transient entities
                    object[] currentState = persister.GetPropertyValues(@event.Entity);
                    dirtyProperties  = persister.FindDirty(entry.DeletedState, currentState, entity, session);
                    cannotDirtyCheck = false;
                }
                else
                {
                    // dirty check against the database snapshot, if possible/necessary
                    object[] databaseSnapshot = GetDatabaseSnapshot(session, persister, id);
                    if (databaseSnapshot != null)
                    {
                        dirtyProperties         = persister.FindModified(databaseSnapshot, values, entity, session);
                        cannotDirtyCheck        = false;
                        @event.DatabaseSnapshot = databaseSnapshot;
                    }
                }
            }
            else
            {
                // the Interceptor handled the dirty checking
                cannotDirtyCheck             = false;
                interceptorHandledDirtyCheck = true;
            }

            @event.DirtyProperties = dirtyProperties;
            @event.DirtyCheckHandledByInterceptor = interceptorHandledDirtyCheck;
            @event.DirtyCheckPossible             = !cannotDirtyCheck;
        }
示例#14
0
        private void WriteAudit(object entity, object[] oldState, IEntityPersister persister, object[] state, IEventSource eventSource, object id)
        {
            IStatelessSession session     = null;
            ITransaction      transaction = null;

            try
            {
                if (entity is AuditLogEntry)
                {
                    return;
                }
                var entityFullName = entity.GetType().FullName;
                if (oldState == null)
                {
                    //Hack to overcome bad saving practice!
                    oldState = Enumerable.Repeat(UnknownString as object, state.Length).ToArray();
                    //throw new ArgumentNullException("No old state available for entity type '" + entityFullName + "'. Make sure you're loading it into Session before modifying and saving it.");
                }


                bool insert = oldState.Length < 1;
                //ISessionImplementor implementor = eventSource.GetSession(EntityMode.Poco).SessionFactory.OpenStatelessSession().GetSessionImplementation();
                int[]  dirtyFieldIndexes = insert ? Enumerable.Range(0, state.Length).ToArray() : persister.FindDirty(state, oldState, entity, eventSource);
                var    auditEntryType    = insert ? "Insert" : "Update";
                string username          = Environment.UserName;

                var haveModifiedBy = entity as IHaveModifiedBy;
                if (haveModifiedBy != null)
                {
                    username = haveModifiedBy.LastModifiedBy;
                }

                session = eventSource.GetSession(EntityMode.Poco).SessionFactory.OpenStatelessSession();
                session.BeginTransaction();
                foreach (var dirtyFieldIndex in dirtyFieldIndexes)
                {
                    string oldValue = NoValueString;
                    if (!insert)
                    {
                        oldValue = GetStringValueFromStateArray(oldState, dirtyFieldIndex);
                    }
                    var newValue     = GetStringValueFromStateArray(state, dirtyFieldIndex);
                    var propertyName = persister.PropertyNames[dirtyFieldIndex];
                    if (oldValue == newValue || propertyName == "LastModifiedBy" || propertyName == "LastModifiedDate")
                    {
                        continue;
                    }

                    session.Insert(new AuditLogEntry
                    {
                        EntityShortName = entity.GetType().Name,
                        FieldName       = propertyName,
                        OldValue        = oldValue,
                        NewValue        = newValue,
                        Username        = username,
                        EntityId        = (int)id,
                        AuditEntryType  = auditEntryType,
                        Timestamp       = DateTime.Now
                    });
                }
                session.Transaction.Commit();
                session.Close();
            }
            catch (Exception)
            {
                //Don't let audit log make us fail.
                //if (session != null)
                //{
                //    if (session.Transaction.IsActive) session.Transaction.Rollback();
                //    session.Close();
                //    session = null;
                //}
                //if (eventSource != null)
                //{
                //    //if (transaction != null && transaction.IsActive) eventSource.Transaction.Rollback();
                //    //if (eventSource.Transaction.IsActive) eventSource.Transaction.Rollback();
                //    //eventSource.Close();
                //}
            }
        }