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