1

我在 3 层场景中使用带有自跟踪实体的 EntityFramework 4。
我的目标是在实体保存回服务器时检测 ObjectContext 的 SavingChanges 处理程序中修改的属性。

注意:

  • 这是一个 3 层场景;因此自跟踪实体保存在另一个 ObjectContext 中,而不是从中获取的那个
  • 自跟踪实体在调用 SaveChanges 之前附加到上下文,并且所有更改都按预期保存。


这是我跟踪修改后的属性的方法:

var objectStateManager = objectContext.ObjectStateManager;
var modifiedObjectStateEntries = objectStateManager
                    .GetObjectStateEntries(EntityState.Modified)
                    .Where(x => !x.IsRelationship);
foreach (var modifiedObjectStateEntry in modifiedObjectStateEntries)
{
    // 需要从数据源刷新,因为这个实体是在另一个上下文中获取的
    objectContext.Refresh(RefreshMode.ClientWins, modifiedObjectStateEntry.Entity);
    var modifiedProperties = modifiedObjectStateEntry.GetModifiedProperties();
}


现在,由于某种原因,modifiedProperties 集合包含所有属性,而不仅仅是那些被修改的属性。知道为什么会这样吗?

当我将 OriginalValues 与 CurrentValues 进行比较时,一切看起来都符合预期。

var originalValues = modifiedObjectStateEntry.OriginalValues;
var currentValues = modifiedObjectStateEntry.CurrentValues;
for (int i = 0; i < originalValues.FieldCount; i++)
{
    // 这工作正常,只检测到差异
    if (!Equals(originalValues.GetValue(i), currentValues.GetValue(i)))
    {
    }
}


知道为什么“modifiedObjectStateEntry.GetModifiedProperties();” 在这种情况下不会像我预期的那样工作?


谢谢你的时间,
科恩

4

1 回答 1

1

我能想到的唯一原因是您正在修改所有属性,因为如果在最后一次 SaveChanges 发出后它们被更改,它们只会显示为该方法的返回。

正如您在MSDN上看到的,它声明: 返回自上次调用 SaveChanges 以来已更改的对象属性的名称

查看您的代码示例,您看到这个的原因是因为您正在刷新实体(这将设置每个属性并将它们标记为已修改)。

...    
objectContext.Refresh(RefreshMode.ClientWins, modifiedObjectStateEntry.Entity);
...

此调用将重置所有属性,而不仅仅是已修改的属性。

我不清楚您要达到什么目的,但是如果要查看更新的内容,您就不能这样做。您需要复制实体并刷新,然后才能检查修改后的字段,但这会很丑陋。

于 2013-03-07T17:44:01.423 回答