2011-06-30 183 views
1

我想知道是否有人可以提供一些插入的審計日誌記錄實施的輸入。我需要確保它是事務性的。審計日誌記錄插入

我在下面的POCO內置的審計DbSet:

public class Audit { 
    public int Id { get; set; } 
    public User User { get; set; } 
    public DateTime Created { get; set; } 
    public string Type { get; set; } 
    public int EntityId { get; set; } 
    public string Message { get; set; } 
} 

我有一個DbSet,據用戶反映,當我做一個插入我想創建自動的審計DbSet添加審計實體。請看下面的代碼:

//var user = new User(); 
//user.Created = DateTime.Now; 
//user.Username = "testuser"; 
//user.Password = "testpassword"; 
//dataContext.Users.Add(user); 

var post = new Post(); 
post.Created = DateTime.Now; 
post.Title = "A sample post"; 
post.Published = true; 
post.Body = "Some content goes in here..."; 

dataContext.Posts.Add(post); 

var audit = new Audit(); 
audit.Created = DateTime.Now; 
audit.User = CurrentUser.User; // Currently logged in user 
audit.Type = "Post.Add"; 
audit.EntityId = post.Id; 
audit.Message = "New post was created"; 

dataContext.Audits.Add(audit); 

dataContext.SaveChanges(); 

在這種情況下,審計的單位將被添加,但「ENTITYID」屬性將被設置爲0(默認值),而不是創建 用戶 後的身份,即身份值(SCOPE_IDENTITY()/ @@ IDENTITY)。

我想保持兩個點在一個單一的交易,而不是分裂的項目爲兩項交易,即堅持在 用戶 後,再堅持審計秒爲有機會審計可能會失敗。

+0

什麼獲得存儲在audit.User在DB?我打賭這是新用戶的真實ID。 –

+0

在audit.User中,我將對當前登錄用戶的引用存儲到應用程序(ASP.NET MVC) - 這樣我就可以跟蹤在系統上執行操作的人員以及日期/時間。 – benno

+0

Ah,gotcha ...正在回答的問題 –

回答

2

覆蓋DbContext.SaveChanges()並查看所有ChangeTracker.Entries()。其中​​(e => e.State!= EntityState.Unchanged)。

這裏是我的A R & d項目的例子:

public override int SaveChanges() 
{ 
    int recordsUpdated = 0; 

    var journalEntries = new List<AuditJournal>(); 

    foreach (var entry in this.ChangeTracker.Entries<ITrackedEntity>().Where(e=>e.State != EntityState.Unchanged)) 
    { 
     AuditJournal journal = new AuditJournal(); 
     journal.Id = Guid.NewGuid(); 
     journal.EntityId = entry.Entity.Id.Value; 
     journal.EntityType = entry.Entity.EntityType; 
     journal.ActionType = entry.State.ToString(); 
     journal.OccurredOn = DateTime.UtcNow; 
     //journal.UserId = CURRENT USER 
     //journal.PreviousEntityData = XML SERIALIZATION OF ORIGINAL ENTITTY 

     journalEntries.Add(journal); 
    } 

    using (var scope = new TransactionScope()) 
    { 
     recordsUpdated = base.SaveChanges(); 

     foreach (var journalEntry in journalEntries) 
      this.AuditJournal.Add(journalEntry); 

     base.SaveChanges(); //Save journal entries 

     scope.Complete(); 
    } 

    return recordsUpdated; 
} 

//Every entity that needs to be audited has to implement this interface 
public interface ITrackedEntity 
{ 
    string EntityType { get; } 
    Guid? Id { get; set; } 
} 
+0

感謝您的示例Bryan - 這與我的一位同事開始關注的路線類似,但並未考慮Xml序列化,但我相信我們會...... – benno

0

如果您不介意將Post的可空引用添加到審計表中,則可以讓EF爲您完成工作。掉落的ENTITYID屬性,並添加到審覈:

public Post Post {get; set;} 

當你記錄事件:

audit.Post = Post; 

EF將插入後,抓住它的ID,並添加在同一來審覈你參考交易。我們在我們自己的AuditEvent模型中做了這件事,我們有幾個可以爲空的引用給我們的各種類型,所以對於任何給定的事件,我們可以鏈接回相關的對象或對象。

+0

我已經考慮過這個問題,但不幸的是我將會有大約30個實體類型,所以我不想在審計中擁有30個不同的屬性,都是可以爲空的。 – benno