为了审计日志记录的目的,我覆盖了EF 4.1数据库优先方法中的SaveChanges()
方法。
我有所有的ObjectStateEntry对象,我想知道是否可以从每个ObjectStateEntry中获取所有键及其值。
IEnumerable<ObjectStateEntry> changes = this.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified);
foreach (ObjectStateEntry stateEntryEntity in changes)
{
if (!stateEntryEntity.IsRelationship &&
stateEntryEntity.Entity != null &&
!(stateEntryEntity.Entity is DBAudit))
{
list<object , object> KeyValues = GetAllKeyValues(stateEntryEntity );
//Do log all keyvalues
}
}
我还没有测试过它,但像这样的东西应该可以工作:
private Dictionary<string, object> GetAllKeyValues(ObjectStateEntry entry)
{
var keyValues = new Dictionary<string, object>();
var currentValues = entry.CurrentValues;
for (int i = 0; i < currentValues.FieldCount; i++)
{
keyValues.Add(currentValues.GetName(i), currentValues.GetValue(i));
}
return keyValues;
}
尝试使用ObjectStateEntry.EntityKey
和EntityKey.EntityKeyValues
:
var keyValues = stateEntityEntry.EntityKey.EntityKeyValues;
返回EntityKeyMember的数组。然后可以使用Key
和Value
属性,它们分别返回string
和object
。
这是我的扩展方法形式的解决方案。
public static class ExtensionMethods
{
public static IReadOnlyDictionary<string, object> GetKeyValues(this ObjectStateEntry instance)
{
var keyMemberNames = instance
.EntitySet
.ElementType
.KeyMembers
.Select(x => x.Name)
.ToList();
var currentValues = instance.CurrentValues;
var result = new Dictionary<string, object>();
for (var i = 0; i < currentValues.FieldCount; i++)
{
var name = currentValues.GetName(i);
if (!keyMemberNames.Contains(name))
continue;
var value = currentValues.GetValue(i);
result.Add(name, value);
}
return result;
}
public static IReadOnlyDictionary<string, object> GetValues(this ObjectStateEntry instance)
{
var currentValues = instance.CurrentValues;
var result = new Dictionary<string, object>();
for (var i = 0; i < currentValues.FieldCount; i++)
{
var name = currentValues.GetName(i);
var value = currentValues.GetValue(i);
result.Add(name, value);
}
return result;
}
}