2011-06-30 71 views
3

我有一個具有許多一對一關係(cascade =「all-delete-orphan」)和集合的實體。檢查實體(屬性和集合)是否髒dirty

我想看看是這個實體是髒的(包括其收藏和屬性/實體不同於一到一個關係),有沒有辦法做到這一點?

我下面this文章,但它沒有涵蓋所有我需要的,任何幫助將不勝感激。

+0

BTW:我想這樣做,以驗證用戶是否可以退出的形式,或者如果我要提醒的未保存的更改他 – dimirc

回答

0

你可以使用一個NHibernate的監聽器,就像這樣:

public class AuditUpdateListener : IPostUpdateEventListener 
{ 
    private const string _noValueString = "*No Value*"; 

    private static string getStringValueFromStateArray(object[] stateArray, int position) 
    { 
     var value = stateArray[position]; 

     return value == null || value.ToString() == string.Empty 
       ? _noValueString 
       : value.ToString(); 
    } 

    public void OnPostUpdate(PostUpdateEvent @event) 
    { 
     if (@event.Entity is AuditLogEntry) 
     { 
      return; 
     } 

     var entityFullName = @event.Entity.GetType().FullName; 

     if (@event.OldState == null) 
     { 
      throw new ArgumentNullException("No old state available for entity type '" + entityFullName + 
              "'. Make sure you're loading it into Session before modifying and saving it."); 
     } 

     int[] dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session); 

     ISession session = @event.Session.GetSession(EntityMode.Poco); 

     string entityName = @event.Entity.GetType().Name; 
     string entityId = @event.Id.ToString(); 

     foreach (int dirtyFieldIndex in dirtyFieldIndexes) 
     { 
      //For component types, check: 
      // @event.Persister.PropertyTypes[dirtyFieldIndex] is ComponentType 

      var oldValue = getStringValueFromStateArray(@event.OldState, dirtyFieldIndex); 
      var newValue = getStringValueFromStateArray(@event.State, dirtyFieldIndex); 

      if (oldValue == newValue) 
      { 
       continue; 
      } 

      // Log 
      session.Save(new AuditLogEntry 
           { 
            EntityShortName = entityName, 
            FieldName = @event.Persister.PropertyNames[dirtyFieldIndex], 
            EntityFullName = entityFullName, 
            OldValue = oldValue, 
            NewValue = newValue, 
            Username = Environment.UserName, 
            EntityId = entityId, 
            AuditEntryType = AuditEntryType.PostUpdate 
           }); 
     } 

     session.Flush(); 
    } 
} 
+0

但是這會在沖洗並且那不是我想要的。另外我不認爲這將通過收藏。 – dimirc

+0

PreUpdateEventListener怎麼樣?這是最好的方法... – rebelliard

1

onFlushDirty(...)方法(在Hibernate中延伸EmptyInterceptor)對我的作品來檢查髒集合。具有嵌套集合的父實體被傳入onFlushDirty,但我不知道傳入的實體可能是集合元素。一旦我發現它,它既適用於嵌套集合,也適用於其父實體。

public class PropertyChangeInterceptor extends EmptyInterceptor{ 

public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) 

另一種方法,onCollectionUpdate(...)也可以用來捕捉骯髒的集合,它onFlushDirty(...)之後被調用。

相關問題