简体   繁体   English

c#实体框架创建审计历史记录

[英]c# Entity Framework creating audit history

I'm using the Entity Framework to construct a basic repository to add/delete/update Customer records. 我正在使用实体框架构建一个基本存储库来添加/删除/更新客户记录。

One thing I want is to be able to have Customer row auditing so that I have a second table CustomerAudit that should get an entry added every time you add/update/delete a row. 我想要的一件事是能够进行客户行审计,以便我有第二个表CustomerAudit,每次添加/更新/删除行时都应该添加一个条目。 In the old wyrld this would be done with a database trigger on update/on delete/on insert etc. Now, I'm trying to do it by overriding the SaveChanges() method of the DBContext object, leveraging the ChangeTracker object and using that to create an audit record based on the data being saved/updated with the current date time and inserting that alongside the actual row. 在旧的wyrld中,这将通过更新/删除/插入等上的数据库触发器来完成。现在,我试图通过覆盖DBContext对象的SaveChanges()方法来实现它,利用ChangeTracker对象并使用它根据使用当前日期时间保存/更新的数据创建审计记录,并将其插入实际行。 Code below. 代码如下。

The problem I have is that when you update or delete, this works fine as it writes the most recent record to the audit table which will have either the updated values or the final values before deletion, along with the current timestamp of when this activity occurred. 我遇到的问题是,当您更新或删除时,这可以正常工作,因为它将最新记录写入审计表,该记录表将具有更新值或删除前的最终值,以及此活动发生时的当前时间戳。

When you add a record though, it inserts a record in the audit table, but as the actual row hasn't been inserted yet (with identity insert) you dont yet have the CustomerId and so it inserts an audit record with the correct data but with a CustomerId of 0, which is no good for auditing. 当您添加记录时,它会在审计表中插入一条记录,但由于尚未插入实际行(带有标识插入),您还没有CustomerId,因此它会插入一个包含正确数据的审计记录但CustomerId为0,这对审计没有好处。

Any thoughts on how I can get the auditing working for adding records to? 有关如何让审计工作添加记录的任何想法?

 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);
        }
    }

获取条目并将它们保存到列表中,然后保存更改,将base.SaveChanges()调用的结果存储在变量中,然后浏览您创建的更改列表并从中创建审计实体,然后return base.SaveChanges() + yourPriorSaveChangesResultVariable;

The answer by @Rob G has solved the purpose though, but here the Audit is done in two transactions. @Rob G的答案已经解决了这个目的,但是这里审计是在两个交易中完成的。 Fist is to Insert the Customer row and second transaction with the CustomerId to CustomerAudit table. Fist是将CustomerId的Customer行和第二个事务插入CustomerAudit表。

I think it is better to create a Foreign Key relation with CustomerId in these tables will generate the same Id for CustomerAudit table as well and that too in the same transaction. 我认为最好在这些表中创建与CustomerId的外键关系,也会为CustomerAudit表生成相同的Id,并且在同一事务中也是如此。

I am new in sharing my ideas to the stackoverflow, but getting help from this for quite long. 我是新手,将我的想法分享给stackoverflow,但是从这里获得了很长时间的帮助。

Please comment if any. 如果有的话请评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM