我正在尝试通过覆盖SaveChangeAsync方法来实现Audit Trail。使用ChangeTracker.Entries(),我可以获得正在修改或添加的所有属性的列表。这适用于没有任何FK的普通实体。但是对于FK,如果我通过导航属性分配了外国实体,ChangeTracker没有检测到相关FK的变化。
让我说我有这些课程
class Parent{
int ParentID,
string Name,
}
class Child {
int ChildID,
int GenderID,
string Name
virtual Gender Gender{get;set;}
}
class ParentChild {
int ParentChildID,
int ParentID,
int ChildID,
string RelationName;
virtual Parent Parent {get;set;}
virtual Child Child {get;set;}
}
插入新记录
Var p = new Parent{ Name="p1"};
var c = new Child {Name ="c1"};
context.ParentChild.Add(new ParentChild {
Parent = p,
Child = c,
RelationName = "First child"
};
context.SaveChangeAsync();
这里的问题是因为我通过导航属性在ParentChild实体中分配父和子,ChangeTracker没有检测到ParentID&amp ;;的任何变化。 ParentChild实体中的ChildID,但DB确实更新了两个FK。
这就是我记录更改的方式
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State != EntityState.Unchanged && p.State != EntityState.Detached).ToList();
var now = DateTime.UtcNow;
List<AuditTemp> changes = new List<AuditTemp>();
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKey = GetPrimaryKeyValue(change) ?? 0;
foreach (var prop in change.CurrentValues.PropertyNames)
{
string originalValue = "";
string currentValue = "";
currentValue = (change.CurrentValues[prop]??"").ToString();
if (change.State == EntityState.Modified)
originalValue = (change.OriginalValues[prop]??"").ToString();
if (originalValue != currentValue)
{
AuditTemp log = new AuditTemp()
{
Entity = change,
Audit = new Audit()
{
TableName = entityName,
FieldName = prop,
OldValue = originalValue,
NewValue = currentValue,
UpdateDate = now
}
};
changes.Add(log);
}
}
}
int a = await base.SaveChangesAsync(cancellationToken);
foreach (var c in changes)
{
c.Audit.NewValue = c.Entity.CurrentValues[c.Audit.FieldName].ToString();
c.Audit.RecordID = Convert.ToInt64(GetPrimaryKeyValue(c.Entity)??0);
this.Audits.Add(c.Audit);
}
await base.SaveChangesAsync(cancellationToken);
return a;
}
我在调用SaveChanges后更新/添加日志以获取Insert的自动生成密钥。
我可以通过任何方式检测FK中的更改(通过导航属性更新)并记录它们。
非常感谢