如何将要插入数据库的对象与尚未使用Entity Framework插入的对象相关联?

时间:2013-09-22 19:44:14

标签: entity-framework asp.net-mvc-4

我正在尝试根据此帖http://jmdority.wordpress.com/2011/07/20/using-entity-framework-4-1-dbcontext-change-tracking-for-audit-logging/在我的MVC 4中使用EF应用程序实施审核。

我有一个继承自DbContext的类并重写了SaveChanges方法。在这个新的SaveChanges方法中,我将一条记录插入到Audit表中。

可以审核的实体:

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相关联?

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

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