1

我正在尝试按照这篇文章http://jmdority.wordpress.com/2011/07/20/using-entity-framework-4-1-dbcontext-change-tracking-for在我的 MVC 4 中使用 EF 应用程序实现审计-审计日志/

我有一个继承自 DbContext 并覆盖 SaveChanges 方法的类。在这个新的 SaveChanges 方法中,我将一条记录插入到审计表中。

可以被审计的实体:

public class Fruit
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long FruitId{ get; set; }

    public string FruitName{ get; set; }
}

FruitAudit 表的模型:

public class FruitAudit
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long FruitAuditId{ get; set; }

    public long FruitId{ get; set; }

    // Auditing properties like modifying user and timestamps.
}

还有我重写的 SaveChanges 方法:

public int SaveChanges()
{
    var entriesToAudit = this.ChangeTracker.Entries().Where(p =>
        (p.State == System.Data.EntityState.Added || p.State == System.Data.EntityState.Deleted || p.State == System.Data.EntityState.Modified);

    foreach (var entity in entriesToAudit)
    {
        using (var context = new StoreContext())
        {
            Fruit fruit = entity.Entity as Fruit;
            FruitAudit audit = new FruitAudit()
            {
                FruitId = Fruit.FruitId;
                // Other auditing properties set here
            }
            context.FruitAudits.Add(audit);
            context.SaveChanges();
        }
    }

    return base.SaveChanges();
}

插入 Fruit 时发生错误,因为在尝试保存 FruitAudit 记录时尚未设置 FruitId。FruitId 是从数据库自动生成的,但实际的 Fruit 对象在插入审计记录之后才会保存。如何将此 FruitAudit 与插入的 Fruit 关联?

4

2 回答 2

0

我建议使用虚拟导航属性,FruitAudit以便您拥有以下内容:

public class FruitAudit
{
    public int FruitAuditId { get; set; }

    public int FruitId { get; set; }
    public virtual Fruit Fruit { get; set; }
}

Fruit看起来像:

public class Fruit
{
    public int FruitId { get; set; }

    public string FruitName { get; set; }
}

然后,当你去找你时,SaveChanges()你只需说:

Fruit fruit = entity.Entity as Fruit;
FruitAudit audit = new FruitAudit()
{
  Fruit = fruit;
  // Other auditing properties set here
}

...

context.Fruits.Add(fruit);
context.FruitAudits.Add(audit);
于 2013-09-22T19:53:31.443 回答
0

我最终制作了所有实体更改的副本,然后调用 base.SaveChanges()。这将插入所有的水果。然后我浏览实体更改的副本并为每个更改插入审计记录。

于 2013-09-24T16:05:04.673 回答