C# 显示实体框架7的原始值
我有一个审计表,跟踪添加、删除和修改。出于多种原因,我在实体框架内跟踪这个过程,而不是使用数据库触发器,但实际上是因为我们使用了一个进程帐户,我想跟踪用户对该记录所做的物理更改 我在EF5中使用过这个工具&我不记得我可能在EF6中也使用过它。无论是哪种方式,我在EF7试图捕捉原始值的过程中都是最困难的 我注意到,当我在手表里时,我可以看到非公众成员的原始价值观,所以在我的头脑中,我知道它一定存在于某个地方 最终,这在EF早期版本中起作用:C# 显示实体框架7的原始值,c#,.net,entity-framework,entity-framework-core,C#,.net,Entity Framework,Entity Framework Core,我有一个审计表,跟踪添加、删除和修改。出于多种原因,我在实体框架内跟踪这个过程,而不是使用数据库触发器,但实际上是因为我们使用了一个进程帐户,我想跟踪用户对该记录所做的物理更改 我在EF5中使用过这个工具&我不记得我可能在EF6中也使用过它。无论是哪种方式,我在EF7试图捕捉原始值的过程中都是最困难的 我注意到,当我在手表里时,我可以看到非公众成员的原始价值观,所以在我的头脑中,我知道它一定存在于某个地方 最终,这在EF早期版本中起作用: EntityEntry dbEntry; //this
EntityEntry dbEntry; //this is actually passed in a different area just showing as an example.
foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
// For updates, we only want to capture the columns that actually changed
if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName), dbEntry.CurrentValues.GetValue<object>(propertyName)))
{
result.Add(new TableChange()
{
AuditLogID = Guid.NewGuid(),
UserID = userId,
EventDateUTC = changeTime,
EventType = "M", // Modified
TableName = tableName,
RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
ColumnName = propertyName,
OriginalValue = dbEntry.OriginalValues.GetValue<object>(propertyName) == null ? null : dbEntry.OriginalValues.GetValue<object>(propertyName).ToString(),
NewValue = dbEntry.CurrentValues.GetValue<object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue<object>(propertyName).ToString()
}
);
}
}
EntityEntry-dbEntry//这实际上是在一个不同的区域中传递的,只是作为一个示例显示。
foreach(dbEntry.OriginalValues.PropertyNames中的字符串propertyName)
{
//对于更新,我们只希望捕获实际更改的列
如果(!object.Equals(dbEntry.OriginalValues.GetValue(propertyName),dbEntry.CurrentValues.GetValue(propertyName)))
{
结果.添加(新表更改()
{
AuditLogID=Guid.NewGuid(),
UserID=UserID,
EventDateUTC=changeTime,
EventType=“M”,//已修改
TableName=TableName,
RecordID=dbEntry.OriginalValues.GetValue(keyName).ToString(),
ColumnName=propertyName,
OriginalValue=dbEntry.OriginalValue.GetValue(propertyName)==null?null:dbEntry.OriginalValue.GetValue(propertyName).ToString(),
NewValue=dbEntry.CurrentValues.GetValue(propertyName)==null?null:dbEntry.CurrentValues.GetValue(propertyName).ToString()
}
);
}
}
我得到的错误是EntityEntry不包含原始值的定义。我要把头发拔出来。。。如何使用EF 7从修改过的对象中获取原始值?另一个选项是仍然使用原始值,但使用属性来代替PropertyNames。这将使foreach循环进程类型为Microsoft.EntityFrameworkCore.Metadata.IProperty。GetValues方法有一个接受IProperty的重载,因此这些调用不需要在代码中进行更改,但需要将ColumnName分配从propertyName更改为propertyName
// using System.Reflection;
foreach (var property in dbEntry.Entity.GetType().GetTypeInfo().DeclaredProperties)
{
var originalValue = dbEntry.Property(property.Name).OriginalValue;
var currentValue = dbEntry.Property(property.Name).CurrentValue;
Console.WriteLine($"{property.Name}: Original: {originalValue}, Current: {currentValue}");
}
foreach(entityEntry.OriginalValues.Properties中的var属性)
{
如果(!object.Equals)(entityEntry.OriginalValues.GetValue(属性),
entityEntry.CurrentValues.GetValue(属性)))
{
结果。添加(
新审核日志()
{
UserId=UserId,
EventDate=changeTime,
EventType=“M”,
TableName=TableName,
RecordId=entityEntry.OriginalValues.GetValue(keyName).ToString(),
ColumnName=property.Name,
原始值=
entityEntry.OriginalValues.GetValue(属性)==null
无效的
:entityEntry.OriginalValues.GetValue(属性).ToString(),
新值=
entityEntry.CurrentValues.GetValue(属性)==null
无效的
:entityEntry.CurrentValues.GetValue(属性).ToString()
});
}
}
这可以通过以下方法解决:dbEntry.GetDatabaseValues()。
下面提到了示例代码
if (dbEntry.State == System.Data.EntityState.Modified)
{
foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
// Caputre current value
var originalValue = dbEntry.GetDatabaseValues().GetValue<object>(propertyName) == null ? null : dbEntry.GetDatabaseValues().GetValue<object>
(propertyName).ToString();
// Caputre Updated value
var currentValue = dbEntry.CurrentValues.GetValue<object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue<object>(propertyName).ToString();
// For updates, we only want to capture the columns that actually changed
if (!object.Equals(!object.Equals(originalValue, currentValue))
{
result.Add(new AuditLog()
{
AuditLogID = Guid.NewGuid(),
UserID = userId,
EventDateUTC = changeTime,
EventType = "M", // Modified
TableName = tableName,
RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
ColumnName = propertyName,
OriginalValue = originalValue,
NewValue = currentValue,
}
);
}
}
}
if(dbEntry.State==System.Data.EntityState.Modified)
{
foreach(dbEntry.OriginalValues.PropertyNames中的字符串propertyName)
{
//卡普特电流值
var originalValue=dbEntry.GetDatabaseValues().GetValue(propertyName)==null?null:dbEntry.GetDatabaseValues().GetValue
(propertyName).ToString();
//Caputre更新值
var currentValue=dbEntry.CurrentValues.GetValue(propertyName)==null?null:dbEntry.CurrentValues.GetValue(propertyName).ToString();
//对于更新,我们只希望捕获实际更改的列
如果(!object.Equals(!object.Equals(originalValue,currentValue))
{
结果.添加(新的审核日志()
{
AuditLogID=Guid.NewGuid(),
UserID=UserID,
EventDateUTC=changeTime,
EventType=“M”,//已修改
TableName=TableName,
RecordID=dbEntry.OriginalValues.GetValue(keyName).ToString(),
ColumnName=propertyName,
原始值=原始值,
NewValue=当前值,
}
);
}
}
}
有一个包含原始值的方法。@ieagle这是EntityFramework 5/6哦,对了,那么你的答案是正确的。包含原始值
并包含返回属性入口
的方法。它是什么语法,包含前缀$
,是什么新功能C#6.0的#无望,是的。这被称为。一如既往,错误处理是可取的。dbEntry.Property(Property.Name)
如果实体类包含未包含在模型中的属性,例如通过[NotMapped]的方式,将抛出InvalidoOperationException如果您只想考虑模型中映射的属性,则可以在“代码> >条目.Basic。GETFrimeStices()/CUT>中循环。这可能也适用,但我没有尝试。坏主意。这为通过该方法的每个实体做了数据库查询。对象图可以很容易地包含几十个实体。
if (dbEntry.State == System.Data.EntityState.Modified)
{
foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
// Caputre current value
var originalValue = dbEntry.GetDatabaseValues().GetValue<object>(propertyName) == null ? null : dbEntry.GetDatabaseValues().GetValue<object>
(propertyName).ToString();
// Caputre Updated value
var currentValue = dbEntry.CurrentValues.GetValue<object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue<object>(propertyName).ToString();
// For updates, we only want to capture the columns that actually changed
if (!object.Equals(!object.Equals(originalValue, currentValue))
{
result.Add(new AuditLog()
{
AuditLogID = Guid.NewGuid(),
UserID = userId,
EventDateUTC = changeTime,
EventType = "M", // Modified
TableName = tableName,
RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
ColumnName = propertyName,
OriginalValue = originalValue,
NewValue = currentValue,
}
);
}
}
}