我正在使用Entity Framework构建一个基本存储库来添加/删除/更新客户记录。
我想要的一件事是能够进行客户行审核,以便我有第二个表CustomerAudit,每次添加/更新/删除行时都应该添加一个条目。在旧的wyrld中,这将通过更新/删除/插入等上的数据库触发器来完成。现在,我试图通过覆盖DBContext对象的SaveChanges()方法来实现它,利用ChangeTracker对象并使用它根据使用当前日期时间保存/更新的数据创建审计记录,并将其插入实际行。代码如下。
我遇到的问题是,当您更新或删除时,这可以正常工作,因为它将最新的记录写入审计表,该记录表将具有更新的值或删除前的最终值,以及当前时间戳的时间戳这个活动发生了。
当您添加记录时,它会在审计表中插入一条记录,但由于尚未插入实际行(带有标识插入),您还没有CustomerId,因此它会插入一条审计记录正确的数据,但CustomerId为0,这对审计没有好处。
有关如何让审核工作添加记录的任何想法?
public class CustomerDbContext : DbContext
{
public CustomerDbContext()
{
Database.SetInitializer(new CreateDatabaseIfNotExists<CustomerDbContext>());
}
public DbSet<Customer> Customers { get; set; }
public DbSet<CustomerAudit> CustomerAudits { get; set; }
public override int SaveChanges()
{
// Get all Added/Deleted/Modified entities (not Unmodified or Detached)
foreach (var ent in ChangeTracker.Entries().Where(p => p.State == System.Data.EntityState.Added || p.State == System.Data.EntityState.Deleted || p.State == System.Data.EntityState.Modified))
{
var auditRecord = GetAuditRecord(ent);
if (auditRecord != null)
CustomerAudits.Add(auditRecord);
}
// Call the original SaveChanges(), which will save both the changes made and the audit records
return base.SaveChanges();
}
private static CustomerAudit GetAuditRecord(DbEntityEntry dbEntry)
{
var changedRecord = dbEntry.Entity as Customer;
return changedRecord == null ? null : new CustomerAudit(changedRecord);
}
}
答案 0 :(得分:3)
获取条目并将其保存到列表中,然后保存更改,将base.SaveChanges()
调用的结果存储在变量中,然后浏览您创建的更改列表并从中创建审计实体,然后return base.SaveChanges() + yourPriorSaveChangesResultVariable;
答案 1 :(得分:1)
@Rob G的答案已经解决了这个目的,但审计是在两个交易中完成的。 Fist是将CustomerId的Customer行和第二个事务插入CustomerAudit表。
我认为在这些表中创建与CustomerId的外键关系更好,也会为CustomerAudit表生成相同的Id,并且在同一事务中也是如此。
我是新手,将我的想法分享给stackoverflow,但是从这里获得了很长时间的帮助。
请评论是否有。