Пример #1
0
        protected virtual async Task CopyValuesAsync(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object[] copiedValues;

            if (foreignKeyDirection.Equals(ForeignKeyDirection.ForeignKeyToParent))
            {
                // this is the second pass through on a merge op, so here we limit the
                // replacement to associations types (value types were already replaced
                // during the first pass)
                copiedValues =
                    await(TypeHelper.ReplaceAssociationsAsync(persister.GetPropertyValues(entity),
                                                              persister.GetPropertyValues(target), persister.PropertyTypes,
                                                              source, target, copyCache, foreignKeyDirection, cancellationToken)).ConfigureAwait(false);
            }
            else
            {
                copiedValues =
                    await(TypeHelper.ReplaceAsync(persister.GetPropertyValues(entity),
                                                  persister.GetPropertyValues(target), persister.PropertyTypes, source, target,
                                                  copyCache, foreignKeyDirection, cancellationToken)).ConfigureAwait(false);
            }

            persister.SetPropertyValues(target, copiedValues);
        }
        protected virtual void CopyValues(IEntityPersister persister, object entity, object target,
                                          ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
        {
            object[] copiedValues;

            if (foreignKeyDirection.Equals(ForeignKeyDirection.ForeignKeyToParent))
            {
                // this is the second pass through on a merge op, so here we limit the
                // replacement to associations types (value types were already replaced
                // during the first pass)
                copiedValues =
                    TypeFactory.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode),
                                                    persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes,
                                                    source, target, copyCache, foreignKeyDirection);
            }
            else
            {
                copiedValues =
                    TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode),
                                        persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target,
                                        copyCache, foreignKeyDirection);
            }

            persister.SetPropertyValues(target, copiedValues, source.EntityMode);
        }
        protected virtual void CopyValues(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache)
        {
            object[] copiedValues =
                TypeHelper.Replace(persister.GetPropertyValues(entity, source.EntityMode),
                                   persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target,
                                   copyCache);

            persister.SetPropertyValues(target, copiedValues, source.EntityMode);
        }
Пример #4
0
        protected virtual async Task CopyValuesAsync(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object[] copiedValues =
                await(TypeHelper.ReplaceAsync(persister.GetPropertyValues(entity),
                                              persister.GetPropertyValues(target), persister.PropertyTypes, source, target,
                                              copyCache, cancellationToken)).ConfigureAwait(false);

            persister.SetPropertyValues(target, copiedValues);
        }
Пример #5
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);
            }
        }
        /// <summary>
        /// Associates a given entity (either transient or associated with another session) to the given session.
        /// </summary>
        /// <param name="event">The event triggering the re-association </param>
        /// <param name="entity">The entity to be associated </param>
        /// <param name="id">The id of the entity. </param>
        /// <param name="persister">The entity's persister instance. </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> An EntityEntry representing the entity within this session. </returns>
        protected async Task <EntityEntry> ReassociateAsync(AbstractEvent @event, object entity, object id, IEntityPersister persister, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (log.IsDebugEnabled())
            {
                log.Debug("Reassociating transient instance: {0}", MessageHelper.InfoString(persister, id, @event.Session.Factory));
            }

            IEventSource source = @event.Session;
            EntityKey    key    = source.GenerateEntityKey(id, persister);

            source.PersistenceContext.CheckUniqueness(key, entity);

            //get a snapshot
            object[] values = persister.GetPropertyValues(entity);
            TypeHelper.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source);
            object version = Versioning.GetVersion(values, persister);

            EntityEntry newEntry = source.PersistenceContext.AddEntity(
                entity,
                persister.IsMutable ? Status.Loaded : Status.ReadOnly,
                values,
                key,
                version,
                LockMode.None,
                true,
                persister,
                false);

            await(new OnLockVisitor(source, id, entity).ProcessAsync(entity, persister, cancellationToken)).ConfigureAwait(false);

            persister.AfterReassociate(entity, source);

            return(newEntry);
        }
        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);
            }
        }
Пример #8
0
        /// <summary>
        /// Возвращает индексы измененных свойств, в том числе типа IPersistentCollection.
        /// </summary>
        public static IList <int> GetDirtyPropsAndCollections(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[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);

            var dirtyProps = GetDirtyProps(session, entity);

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

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

            return(dirty);
        }
Пример #9
0
        /// <summary>
        /// Associates a given entity (either transient or associated with another session) to the given session.
        /// </summary>
        /// <param name="event">The event triggering the re-association </param>
        /// <param name="entity">The entity to be associated </param>
        /// <param name="id">The id of the entity. </param>
        /// <param name="persister">The entity's persister instance. </param>
        /// <returns> An EntityEntry representing the entity within this session. </returns>
        protected EntityEntry Reassociate(AbstractEvent @event, object entity, object id, IEntityPersister persister)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("Reassociating transient instance: " +
                          MessageHelper.InfoString(persister, id, @event.Session.Factory));
            }

            IEventSource source = @event.Session;
            EntityKey    key    = new EntityKey(id, persister, source.EntityMode);

            source.PersistenceContext.CheckUniqueness(key, entity);

            //get a snapshot
            object[] values = persister.GetPropertyValues(entity, source.EntityMode);
            TypeFactory.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source);
            object version = Versioning.GetVersion(values, persister);

            EntityEntry newEntry = source.PersistenceContext.AddEntity(entity, Status.Loaded, values, key, version, LockMode.None, true, persister, false, true);

            new OnLockVisitor(source, id, entity).Process(entity, persister);

            persister.AfterReassociate(entity, source);

            return(newEntry);
        }
Пример #10
0
 /// <summary> Insert a row. </summary>
 /// <param name="entityName">The entityName for the entity to be inserted </param>
 /// <param name="entity">a new transient instance </param>
 /// <returns> the identifier of the instance </returns>
 public object Insert(string entityName, object entity)
 {
     using (new SessionIdLoggingContext(SessionId))
     {
         CheckAndUpdateSessionStatus();
         IEntityPersister persister = GetEntityPersister(entityName, entity);
         object           id        = persister.IdentifierGenerator.Generate(this, entity);
         object[]         state     = persister.GetPropertyValues(entity);
         if (persister.IsVersioned)
         {
             object versionValue = state[persister.VersionProperty];
             bool   substitute   = Versioning.SeedVersion(state, persister.VersionProperty, persister.VersionType,
                                                          persister.IsUnsavedVersion(versionValue), this);
             if (substitute)
             {
                 persister.SetPropertyValues(entity, state);
             }
         }
         if (id == IdentifierGeneratorFactory.PostInsertIndicator)
         {
             id = persister.Insert(state, entity, this);
         }
         else
         {
             persister.Insert(id, state, entity, this);
         }
         persister.SetIdentifier(entity, id);
         return(id);
     }
 }
Пример #11
0
        private async Task <object[]> GetValuesAsync(object entity, EntityEntry entry, bool mightBeDirty, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object[]         loadedState = entry.LoadedState;
            Status           status      = entry.Status;
            IEntityPersister persister   = entry.Persister;

            object[] values;
            if (status == Status.Deleted)
            {
                //grab its state saved at deletion
                values = entry.DeletedState;
            }
            else if (!mightBeDirty && loadedState != null)
            {
                values = loadedState;
            }
            else
            {
                CheckId(entity, persister, entry.Id);

                // grab its current state
                values = persister.GetPropertyValues(entity);

                await(CheckNaturalIdAsync(persister, entry, values, loadedState, session, cancellationToken)).ConfigureAwait(false);
            }
            return(values);
        }
Пример #12
0
 /// <summary> Insert a row. </summary>
 /// <param name="entityName">The entityName for the entity to be inserted </param>
 /// <param name="entity">a new transient instance </param>
 /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
 /// <returns> the identifier of the instance </returns>
 public async Task <object> InsertAsync(string entityName, object entity, CancellationToken cancellationToken = default(CancellationToken))
 {
     cancellationToken.ThrowIfCancellationRequested();
     using (new SessionIdLoggingContext(SessionId))
     {
         CheckAndUpdateSessionStatus();
         IEntityPersister persister = GetEntityPersister(entityName, entity);
         object           id        = await(persister.IdentifierGenerator.GenerateAsync(this, entity, cancellationToken)).ConfigureAwait(false);
         object[]         state     = persister.GetPropertyValues(entity);
         if (persister.IsVersioned)
         {
             object versionValue = state[persister.VersionProperty];
             bool   substitute   = await(Versioning.SeedVersionAsync(state, persister.VersionProperty, persister.VersionType,
                                                                     persister.IsUnsavedVersion(versionValue), this, cancellationToken)).ConfigureAwait(false);
             if (substitute)
             {
                 persister.SetPropertyValues(entity, state);
             }
         }
         if (id == IdentifierGeneratorFactory.PostInsertIndicator)
         {
             id = await(persister.InsertAsync(state, entity, this, cancellationToken)).ConfigureAwait(false);
         }
         else
         {
             await(persister.InsertAsync(id, state, entity, this, cancellationToken)).ConfigureAwait(false);
         }
         persister.SetIdentifier(entity, id);
         return(id);
     }
 }
Пример #13
0
        private object[] GetValues(object entity, EntityEntry entry, bool mightBeDirty, ISessionImplementor session)
        {
            object[]         loadedState = entry.LoadedState;
            Status           status      = entry.Status;
            IEntityPersister persister   = entry.Persister;

            object[] values;
            if (status == Status.Deleted)
            {
                //grab its state saved at deletion
                values = entry.DeletedState;
            }
            else if (!mightBeDirty && loadedState != null)
            {
                values = loadedState;
            }
            else
            {
                CheckId(entity, persister, entry.Id);

                // grab its current state
                values = persister.GetPropertyValues(entity);

                CheckNaturalId(persister, entry, values, loadedState, session);
            }
            return(values);
        }
Пример #14
0
        public static Boolean IsDirtyEntity(this ISession session, Object entity)
        {
            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(false);
            }

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

            Object[] oldState = oldEntry.LoadedState;
            if (oldState == null)
            {
                return(false);
            }

            Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);
            Int32[]  dirtyProps   = oldState.Select((o, i) => ValuesAreEqual(oldState[i], currentState[i]) ? -1 : i).Where(x => x >= 0).ToArray();

            return(dirtyProps != null && dirtyProps.Length > 0);
        }
		/// <summary>
		/// Associates a given entity (either transient or associated with another session) to the given session.
		/// </summary>
		/// <param name="event">The event triggering the re-association </param>
		/// <param name="entity">The entity to be associated </param>
		/// <param name="id">The id of the entity. </param>
		/// <param name="persister">The entity's persister instance. </param>
		/// <returns> An EntityEntry representing the entity within this session. </returns>
		protected EntityEntry Reassociate(AbstractEvent @event, object entity, object id, IEntityPersister persister)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("Reassociating transient instance: " + MessageHelper.InfoString(persister, id, @event.Session.Factory));
			}

			IEventSource source = @event.Session;
			EntityKey key = source.GenerateEntityKey(id, persister);

			source.PersistenceContext.CheckUniqueness(key, entity);

			//get a snapshot
			object[] values = persister.GetPropertyValues(entity, source.EntityMode);
			TypeHelper.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source);
			object version = Versioning.GetVersion(values, persister);

			EntityEntry newEntry = source.PersistenceContext.AddEntity(
				entity,
				persister.IsMutable ? Status.Loaded : Status.ReadOnly,
				values,
				key,
				version,
				LockMode.None,
				true,
				persister,
				false,
				true);

			new OnLockVisitor(source, id, entity).Process(entity, persister);

			persister.AfterReassociate(entity, source);

			return newEntry;
		}
Пример #16
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);
        }
Пример #17
0
 /// <summary> Insert a row. </summary>
 /// <param name="entityName">The entityName for the entity to be inserted </param>
 /// <param name="entity">a new transient instance </param>
 /// <param name="bulk"></param>
 /// <returns> the identifier of the instance </returns>
 public object Insert(string entityName, object entity, bool bulk = false)
 {
     using (BeginProcess())
     {
         IEntityPersister persister = GetEntityPersister(entityName, entity);
         object           id        = persister.IdentifierGenerator.Generate(this, entity);
         object[]         state     = persister.GetPropertyValues(entity);
         if (persister.IsVersioned)
         {
             object versionValue = state[persister.VersionProperty];
             bool   substitute   = Versioning.SeedVersion(state, persister.VersionProperty, persister.VersionType,
                                                          persister.IsUnsavedVersion(versionValue), this);
             if (substitute)
             {
                 persister.SetPropertyValues(entity, state);
             }
         }
         if (id == IdentifierGeneratorFactory.PostInsertIndicator)
         {
             id = persister.Insert(state, entity, this, bulk);
         }
         else
         {
             persister.Insert(id, state, entity, this);
         }
         persister.SetIdentifier(entity, id);
         return(id);
     }
 }
Пример #18
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]);
        }
Пример #19
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);
    }
Пример #20
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="persister"></param>
		/// <param name="session"></param>
		/// <returns></returns>
		private static object[] Disassemble(object obj, IEntityPersister persister, ISessionImplementor session)
		{
			object[] values = persister.GetPropertyValues(obj);
			IType[] propertyTypes = persister.PropertyTypes;
			for (int i = 0; i < values.Length; i++)
			{
				values[i] = propertyTypes[i].Disassemble(values[i], session);
			}
			return values;
		}
Пример #21
0
 internal override void Process(object obj, IEntityPersister persister)
 {
     object[] values = persister.GetPropertyValues(obj);
     IType[]  types  = persister.PropertyTypes;
     ProcessEntityPropertyValues(values, types);
     if (SubstitutionRequired)
     {
         persister.SetPropertyValues(obj, values);
     }
 }
Пример #22
0
		internal override void Process(object obj, IEntityPersister persister)
		{
			EntityMode entityMode = Session.EntityMode;
			object[] values = persister.GetPropertyValues(obj, entityMode);
			IType[] types = persister.PropertyTypes;
			ProcessEntityPropertyValues(values, types);
			if (SubstitutionRequired)
			{
				persister.SetPropertyValues(obj, values, entityMode);
			}
		}
Пример #23
0
 internal override async Task ProcessAsync(object obj, IEntityPersister persister, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     object[] values = persister.GetPropertyValues(obj);
     IType[]  types  = persister.PropertyTypes;
     await(ProcessEntityPropertyValuesAsync(values, types, cancellationToken)).ConfigureAwait(false);
     if (SubstitutionRequired)
     {
         persister.SetPropertyValues(obj, values);
     }
 }
        public static Boolean IsDirtyEntity(this ISession session, Object entity)
        {
            EntityEntry      oldEntry;
            IEntityPersister persister = GetEntityPersister(session, entity, out oldEntry);

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

            Int32[] dirtyProps = oldState.Select((o, i) => (oldState[i] == currentState[i]) ? -1 : i).Where(x => x >= 0).ToArray();
            return(dirtyProps != null);
        }
        public static T Attach <T>(this ISession session, T entity, LockMode mode = null)
        {
            mode = mode ?? LockMode.None;

            IEntityPersister persister = session.GetSessionImplementation().GetEntityPersister(NHibernateProxyHelper.GuessClass(entity).FullName, entity);

            Object[]    fields  = persister.GetPropertyValues(entity, session.ActiveEntityMode);
            Object      id      = persister.GetIdentifier(entity, session.ActiveEntityMode);
            Object      version = persister.GetVersion(entity, session.ActiveEntityMode);
            EntityEntry entry   = session.GetSessionImplementation().PersistenceContext.AddEntry(entity, Status.Loaded, fields, null, id, version, LockMode.None, true, persister, true, false);

            return(entity);
        }
        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);
        }
Пример #27
0
        /// <summary>
        /// Perform the entity deletion.  Well, as with most operations, does not
        /// really perform it; just schedules an action/execution with the
        /// <see cref="ActionQueue"/> for execution during flush.
        /// </summary>
        /// <param name="session">The originating session </param>
        /// <param name="entity">The entity to delete </param>
        /// <param name="entityEntry">The entity's entry in the <see cref="ISession"/> </param>
        /// <param name="isCascadeDeleteEnabled">Is delete cascading enabled? </param>
        /// <param name="persister">The entity persister. </param>
        /// <param name="transientEntities">A cache of already deleted entities. </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        protected virtual async Task DeleteEntityAsync(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet <object> transientEntities, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (log.IsDebugEnabled())
            {
                log.Debug("deleting {0}", MessageHelper.InfoString(persister, entityEntry.Id, session.Factory));
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;

            IType[] propTypes = persister.PropertyTypes;
            object  version   = entityEntry.Version;

            object[] currentState;
            if (entityEntry.LoadedState == null)
            {
                //ie. the entity came in from update()
                currentState = persister.GetPropertyValues(entity);
            }
            else
            {
                currentState = entityEntry.LoadedState;
            }

            object[] deletedState = CreateDeletedState(persister, currentState, session);
            entityEntry.DeletedState = deletedState;

            session.Interceptor.OnDelete(entity, entityEntry.Id, deletedState, persister.PropertyNames, propTypes);

            // before any callbacks, etc, so subdeletions see that this deletion happened first
            persistenceContext.SetEntryStatus(entityEntry, Status.Deleted);
            EntityKey key = session.GenerateEntityKey(entityEntry.Id, persister);

            await(CascadeBeforeDeleteAsync(session, persister, entity, entityEntry, transientEntities, cancellationToken)).ConfigureAwait(false);

            await(new ForeignKeys.Nullifier(entity, true, false, session).NullifyTransientReferencesAsync(entityEntry.DeletedState, propTypes, cancellationToken)).ConfigureAwait(false);
            new Nullability(session).CheckNullability(entityEntry.DeletedState, persister, true);
            persistenceContext.NullifiableEntityKeys.Add(key);

            // Ensures that containing deletions happen before sub-deletions
            session.ActionQueue.AddAction(new EntityDeleteAction(entityEntry.Id, deletedState, version, entity, persister, isCascadeDeleteEnabled, session));

            await(CascadeAfterDeleteAsync(session, persister, entity, transientEntities, cancellationToken)).ConfigureAwait(false);

            // the entry will be removed after the flush, and will no longer
            // override the stale snapshot
            // This is now handled by removeEntity() in EntityDeleteAction
            //persistenceContext.removeDatabaseSnapshot(key);
        }
Пример #28
0
 /// <summary>
 /// Walk the tree starting from the given entity.
 /// </summary>
 /// <param name="obj"></param>
 /// <param name="persister"></param>
 /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
 internal virtual Task ProcessAsync(object obj, IEntityPersister persister, CancellationToken cancellationToken)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return(Task.FromCanceled <object>(cancellationToken));
     }
     try
     {
         return(ProcessEntityPropertyValuesAsync(persister.GetPropertyValues(obj), persister.PropertyTypes, cancellationToken));
     }
     catch (System.Exception ex)
     {
         return(Task.FromException <object>(ex));
     }
 }
Пример #29
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);
        }
Пример #30
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 bool IsDirtyEntity(this ISession session, object entity, bool checkCollections = false)
        {
            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);
            }
            if (oldEntry == null)
            {
                return(true);
            }
            string           className = oldEntry.EntityName;
            IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

            object[] oldState     = oldEntry.LoadedState;
            object[] currentState = persister.GetPropertyValues(entity);
            //Int32[] dirtyProps = oldState.Select((o, i) => (oldState[i] == currentState[i]) ? -1 : i).Where(x => x >= 0).ToArray();
            int[] dirtyProps = oldState.Select((o, i) =>
            {
                if (oldState[i] == null && currentState[i] == null)
                {
                    return(-1);
                }
                return((oldState[i] != null && oldState[i].Equals(currentState[i])) ? -1 : i);
            }).Where(x => x >= 0).ToArray();
            if (dirtyProps.Length > 0)
            {
                return(true);
            }
            if (checkCollections)
            {
                foreach (var o in currentState)
                {
                    var collection = o as IPersistentCollection;
                    if (collection != null && collection.IsDirty)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        public static bool HasProxy(this ISession session, Object entity)
        {
            EntityEntry      oldEntry;
            IEntityPersister persister = GetEntityPersister(session, entity, out oldEntry);

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

            foreach (var i in currentState)
            {
                // NHibernateUtil.IsInitialized
                if (NHibernateHelper.IsProxy(i))
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #33
0
        private bool HasDirtyProperties(FlushEntityEvent @event)
        {
            ISessionImplementor session = @event.Session;
            EntityEntry         entry   = @event.EntityEntry;
            var entity = @event.Entity;

            if (!entry.RequiresDirtyCheck(entity) || !entry.ExistsInDatabase || entry.LoadedState == null)
            {
                return(false);
            }
            IEntityPersister persister = entry.Persister;

            object[] currentState = persister.GetPropertyValues(entity, session.EntityMode);;
            object[] loadedState  = entry.LoadedState;

            return(persister.EntityMetamodel.Properties
                   .Where((property, i) => !LazyPropertyInitializer.UnfetchedProperty.Equals(currentState[i]) && property.Type.IsDirty(loadedState[i], currentState[i], session))
                   .Any());
        }
Пример #34
0
		public override void Process(object obj, IEntityPersister persister)
		{
			object[] values = persister.GetPropertyValues(obj);
			IType[] types = persister.PropertyTypes;
			ProcessValues(values, types);
			if (IsSubstitutionRequired)
			{
				persister.SetPropertyValues(obj, values);
			}
		}
Пример #35
0
		private object[] GetPropertyValues(IEntityPersister persister, ICriteria criteria, ICriteriaQuery criteriaQuery)
		{
			System.Type type = _entity.GetType();
			if(type == persister.GetMappedClass(GetEntityMode(criteria, criteriaQuery))) //not using anon object
			{
				return persister.GetPropertyValues(_entity, GetEntityMode(criteria, criteriaQuery));
			}
			ArrayList list = new ArrayList();
			for(int i = 0; i < persister.PropertyNames.Length; i++)
			{
				PropertyInfo pInfo = type.GetProperty(persister.PropertyNames[i]);
				if(pInfo != null)
				{
					list.Add(pInfo.GetValue(_entity, null));
				}
				else
				{
					list.Add(null); //to maintain same order as PropertyNames list
					_excludedProperties.Add(persister.PropertyNames[i]); //exclude the properties that aren't in the anon object (duplicates ok)
				}
			}
			return list.ToArray();
		}
		/// <summary>
		/// Walk the tree starting from the given entity.
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="persister"></param>
		public virtual void Process(object obj, IEntityPersister persister)
		{
			ProcessValues(
				persister.GetPropertyValues(obj),
				persister.PropertyTypes);
		}
		/// <summary>
		/// Walk the tree starting from the given entity.
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="persister"></param>
		internal virtual void Process(object obj, IEntityPersister persister)
		{
			ProcessEntityPropertyValues(persister.GetPropertyValues(obj, Session.EntityMode), persister.PropertyTypes);
		}
Пример #38
0
        /// <summary> 
        /// Perform the entity deletion.  Well, as with most operations, does not
        /// really perform it; just schedules an action/execution with the
        /// <see cref="ActionQueue"/> for execution during flush. 
        /// </summary>
        /// <param name="session">The originating session </param>
        /// <param name="entity">The entity to delete </param>
        /// <param name="entityEntry">The entity's entry in the <see cref="ISession"/> </param>
        /// <param name="isCascadeDeleteEnabled">Is delete cascading enabled? </param>
        /// <param name="persister">The entity persister. </param>
        /// <param name="transientEntities">A cache of already deleted entities. </param>
        protected virtual void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("deleting " + MessageHelper.InfoString(persister, entityEntry.Id, session.Factory));
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;

            IType[] propTypes = persister.PropertyTypes;
            object version = entityEntry.Version;

            object[] currentState;
            if (entityEntry.LoadedState == null)
            {
                //ie. the entity came in from update()
                currentState = persister.GetPropertyValues(entity, session.EntityMode);
            }
            else
            {
                currentState = entityEntry.LoadedState;
            }

            object[] deletedState = CreateDeletedState(persister, currentState, session);
            entityEntry.DeletedState = deletedState;

            session.Interceptor.OnDelete(entity, entityEntry.Id, deletedState, persister.PropertyNames, propTypes);

            // before any callbacks, etc, so subdeletions see that this deletion happened first
            persistenceContext.SetEntryStatus(entityEntry, Status.Deleted);
            EntityKey key = new EntityKey(entityEntry.Id, persister, session.EntityMode);

            CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);

            new ForeignKeys.Nullifier(entity, true, false, session).NullifyTransientReferences(entityEntry.DeletedState, propTypes);
            new Nullability(session).CheckNullability(entityEntry.DeletedState, persister, true);
            persistenceContext.NullifiableEntityKeys.Add(key);

            // Ensures that containing deletions happen before sub-deletions
            session.ActionQueue.AddAction(new EntityDeleteAction(entityEntry.Id, deletedState, version, entity, persister, isCascadeDeleteEnabled, session));

            CascadeAfterDelete(session, persister, entity, transientEntities);

            // the entry will be removed after the flush, and will no longer
            // override the stale snapshot
            // This is now handled by removeEntity() in EntityDeleteAction
            //persistenceContext.removeDatabaseSnapshot(key);
        }
Пример #39
0
		protected virtual void CopyValues(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache)
		{
			object[] copiedValues =
				TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode),
				                    persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target,
				                    copyCache);

			persister.SetPropertyValues(target, copiedValues, source.EntityMode);
		}
Пример #40
0
		protected virtual void CopyValues(IEntityPersister persister, object entity, object target,
			ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
		{
			object[] copiedValues;

			if (foreignKeyDirection == ForeignKeyDirection.ForeignKeyToParent)
			{
				// this is the second pass through on a merge op, so here we limit the
				// replacement to associations types (value types were already replaced
				// during the first pass)
				copiedValues =
					TypeFactory.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode),
					                                persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes,
					                                source, target, copyCache, foreignKeyDirection);
			}
			else
			{
				copiedValues =
					TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode),
					                    persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target,
					                    copyCache, foreignKeyDirection);
			}

			persister.SetPropertyValues(target, copiedValues, source.EntityMode);
		}