3层场景中的EntityFramework的ObjectStateEntry.GetModifiedProperties

时间:2013-02-26 09:31:33

标签: entity-framework

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

请注意:

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


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

var objectStateManager = objectContext.ObjectStateManager;
var modifiedObjectStateEntries = objectStateManager
                    .GetObjectStateEntries(EntityState.Modified)
                    .Where(x => !x.IsRelationship);
foreach (var modifiedObjectStateEntry in modifiedObjectStateEntries)
{
    // need to refresh from datasource, since this entity was fetched in another context
    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++)
{
    // this works fine, only diffs are detected
    if (!Equals(originalValues.GetValue(i), currentValues.GetValue(i)))
    {
    }
}


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


谢谢你的时间,
柯恩

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

我不清楚你想要实现什么,但是如果要看到更新的内容你就不能这样做了。您需要制作一个实体的副本并刷新,然后才能检查修改后的字段,但这样会很难看。