我,在我過去的應用程序,我的審計記錄變化分貝這樣:審計記錄更改與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
笑,爲什麼-1這個問題? –