2014-06-16 58 views
-1

我,在我過去的應用程序,我的審計記錄變化分貝這樣:審計記錄更改與NHibernate

爲每個表這就是需要我加5場

  • ROWID
  • 用戶ID
  • CREATEDATE
  • CHANGEDATE
  • 刪除

,並添加一個觀點,即過濾Deleted = false和輸出的唯一標準領域

全部刪除和更新操作是由存儲過程,多數民衆贊成由管理正確的領域:每次更新或刪除成爲集刪除標誌,並和創建一個新的記錄(僅適用於更新)

這樣,我可以簡單地訪問表,看看誰做出了改變,容易回滾時刪除實際最終記錄設置刪除= false添加到所需的一個

在我的新應用程序中,我需要類似的東西,但我打算使用Nhiber nate,所以我會盡量避免存儲過程,還有其他方法可以做到嗎?可能沒有觸發器

我讀How to efficiently version records in an SQL database,但不喜歡od有一個重複的表的想法:面對現有的記錄,看起來老似乎回滾更困難。

我覺得Envers但它也創建一個重複表

編輯

感謝科爾W¯¯建議,我已經實現了NH事件監聽器是這樣說的:

public class AuditEventListener: DefaultDeleteEventListener, IPreUpdateEventListener, IDeleteEventListener 
    { 
     protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities) 
     { 
      if (entity is LoggedEntity) 
      { 
       var e = (LoggedEntity)entity; 
       e.Annullato = true; 
       e.DataModifica = DateTime.Now; 

       CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities); 
       CascadeAfterDelete(session, persister, entityEntry, transientEntities); 
      } 
      else 
      { 
       base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities); 
      } 
     } 

     public bool OnPreUpdate(PreUpdateEvent eventItem) 
     { 
      if (eventItem.Entity is LoggedEntity) 
      { 
       DateTime dataModifica = DateTime.Now; 
       store(eventItem.Persister, eventItem.State, "modified_date", dataModifica); 
       return false; 
      } 
      else 
       return false; 

     } 

     private void store(IEntityPersister persister, object[] state, string property_name, object value) 
     { 
      int index = Array.IndexOf(persister.PropertyNames, property_name); 
      if (index == -1) 
      { 
       return; 
      } 
      state[index] = value; 
     } 
    } 

這是以流暢的方式配置:

 FluentConfiguration configuration = Fluently.Configure() 
      .Database(config) 
      .Mappings(m => 
       { 
        m.FluentMappings 
         .AddFromAssemblyOf<Class1Map>(); 
        m.AutoMappings.Add(
         AutoMap.AssemblyOf<Class1>(new NHAutoMapConfiguration())); 
       }) 
      .ExposeConfiguration(cfg => 
      { 
       cfg.EventListeners.DeleteEventListeners = 
        new DefaultDeleteEventListener[] { new AuditEventListener() }; 
       cfg.EventListeners.PreUpdateEventListeners = 
        new IPreUpdateEventListener[] { new AuditEventListener() }; 
      }); 

我不喜歡的唯一方法是定義哪些對象需要登錄:我無法使用接口,因爲我將被迫重新定義涉及的所有對象的屬性,所以我創建了一個基礎對象感興趣的擴展,但通過這種方式,這些屬性在我的域外部可見(我不能讓它成爲私有的或內部的,因爲數據訪問層中的NHibernate必須具有訪問權限)。

我認爲最終選擇是在這條道路之間的這個問題,而不是envers,這將離開乾淨我的領域對象,但會創建額外的表在db 我認爲最終選擇是在這條道路之間問題而不是envers,這會讓我清理我的物品,但會創建額外的表db

+0

笑,爲什麼-1這個問題? –

回答