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); }
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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); } }
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); }
/// <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); } }
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); }
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; }
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); }
/// <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); } }
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]); }
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); }
/// <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; }
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); } }
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); } }
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); }
/// <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); }
/// <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)); } }
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); }
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); }
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()); }
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); } }
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); }
/// <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); }
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); }
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); }