C# 显示实体框架7的原始值

C# 显示实体框架7的原始值,c#,.net,entity-framework,entity-framework-core,C#,.net,Entity Framework,Entity Framework Core,我有一个审计表,跟踪添加、删除和修改。出于多种原因,我在实体框架内跟踪这个过程,而不是使用数据库触发器,但实际上是因为我们使用了一个进程帐户,我想跟踪用户对该记录所做的物理更改 我在EF5中使用过这个工具&我不记得我可能在EF6中也使用过它。无论是哪种方式,我在EF7试图捕捉原始值的过程中都是最困难的 我注意到,当我在手表里时,我可以看到非公众成员的原始价值观,所以在我的头脑中,我知道它一定存在于某个地方 最终,这在EF早期版本中起作用: EntityEntry dbEntry; //this

我有一个审计表,跟踪添加、删除和修改。出于多种原因,我在实体框架内跟踪这个过程,而不是使用数据库触发器,但实际上是因为我们使用了一个进程帐户,我想跟踪用户对该记录所做的物理更改

我在EF5中使用过这个工具&我不记得我可能在EF6中也使用过它。无论是哪种方式,我在EF7试图捕捉原始值的过程中都是最困难的

我注意到,当我在手表里时,我可以看到非公众成员的原始价值观,所以在我的头脑中,我知道它一定存在于某个地方

最终,这在EF早期版本中起作用:

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,
                    }
                );
        }
    }
}