我确定这是重复的,但我似乎无法在SO或谷歌上找到我想要的内容。
我正在设置数据审核,以通过Entity Framework 5(数据库优先)跟踪特定实体的更改。我正在使用单个日志表,它将跟踪字段/列级别的更改。我想跟踪表名(不是实体名)和列名(不是实体字段名)。
我使用MetaDataWorkspace尝试过很多东西,但似乎无法获得我想要的确切结果。我不包括元数据代码,因为它没有真正富有成效。请注意,我遇到的一个问题是我的实体在运行时实际上是一个动态代理。
这是我目前的代码:
IEnumerable<DbEntityEntry> entities =
context.ChangeTracker.Entries()
.Where(
e =>
e.State == EntityState.Added || e.State == EntityState.Modified);
bool auditingRequired = false;
var auditEntities = new List<AuditEntity>();
foreach (DbEntityEntry entity in entities)
{
//IFullyAudited is a marker for the entities I want to track
if (!(entity.Entity is IFullyAudited)) continue;
auditingRequired = true;
//note that entity.Entity is actually a dynamic proxy here
string tableName = ""; //how can I get the actual table name (not the entity name)
//there would be different logic for adds and edits--this just covers edits
foreach (string propertyName in entity.OriginalValues.PropertyNames)
{
string columnName = ""; //how can I get the actual column name?
var currentValue = entity.CurrentValues.GetValue<object>(propertyName);
var originalValue = entity.OriginalValues.GetValue<object>(propertyName);
if (!Equals(currentValue, originalValue))
{
//just a fake/POCO, not a real EF Entity until I figure this out
auditEntities.Add(new AuditEntity
{
//save PK here as well
ColumnName = columnName,
TableName = tableName,
NewValue = currentValue.ToString(),
OldValue = originalValue.ToString()
});
}
}
}
if (auditingRequired)
{
//here I will add the audit entity to the context
}