审核日志插入
本文关键字:插入 日志 | 更新日期: 2023-09-27 18:00:52
我想知道是否有人能为插入的审计日志的实现提供一些输入。我需要确保它是事务性的。
我有一个基于以下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,比如Users,当我插入时,我想创建它,并在Audit DbSet中自动添加一个Audit实体。考虑以下代码:
//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(。
我希望将这两个点都保留在一个事务中,而不是将项目拆分为两个事务,即先保留用户帖子,然后再保留审核,因为审核可能会失败。
覆盖DbContext.SaveChanges((并查看所有ChangeTracker.Entries((。其中(e=>e.State!=EntityState.Unchanged(.
以下是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; }
}
如果您不介意在Audit表中添加对Post的可为null的引用,您可以让EF为您做这项工作。删除EntityId属性并添加到Audit:
public Post Post {get; set;}
当你记录事件时:
audit.Post = Post;
EF将插入Post,获取其ID,并在同一交易中为您添加对Audit的引用。我们在自己的AuditEvent模型中做这件事,我们对各种类型有几个可为null的引用,因此对于任何给定的事件,我们都可以链接回相关的一个或多个对象。