3

我确定这是重复的,但我似乎无法在 SO 或通过谷歌找到我正在寻找的确切内容。

我正在设置数据审计以通过实体框架 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
}
4

0 回答 0