我正在尝试根据此帖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相关联?
答案 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()。这将插入所有水果。然后,我查看实体更改的副本,并为每个更改插入审核记录。