如何强制ChangeTracker将当前对象状态重置为Unchanged而不放弃更改

时间:2013-10-23 13:28:43

标签: c# entity-framework

我试图找出如何让EntityFramework认为实体的当前状态不变。

我尝试这样做的原因是实体连接到“模板”实体(1对1关系),如果它们对于当前实体为null,则它继承值。

执行ObjectMaterialized事件时会发生模板属性继承,这是实体状态变为EntityState.Modified的时候。

现在将状态设置为EntityState.Unchanged不起作用(状态仍然被修改,它是否应该像这样?)。我试图通过调用Detach和Attach来解决这个问题,但是存在一些参考问题,因为我怀疑Entity Framework(6 pre)正在找到重复的关系。

问题的来源似乎是字节数组属性,其中我使用以下代码重置:

            var entry = context.Entry(this);
            foreach(var p in entry.CurrentValues.PropertyNames.Where(p => entry.Property(p).IsModified))
            {
                if(entry.CurrentValues[p] is byte[])
                {
                    entry.OriginalValues[p] = (entry.CurrentValues[p] as byte[])/*.ToArray()*/;
                }
                else
                {
                    entry.OriginalValues[p] = entry.CurrentValues[p];
                }
            }
            entry.State = EntityState.Unchanged;

当使用entry.State读取条目状态时,它再次变为Modified并且entry.CurrentValues.PropertyNames.Where(x => entry.Property(x).IsModified)返回一个条目:byte array。我比较了数组,它们完全相同!我还尝试将数组的克隆分配给OriginalValues [propertyName]但没有成功。

我的问题是当它包含EF的字节数组时,如何将实体状态重置为Unchanged,以便认为该对象是从数据库中检索到的,就像现在一样?

2 个答案:

答案 0 :(得分:2)

ObjectStatemanager仅记录项目是否已更改。它不反映条目是否与数据库相同,即没有涉及魔法。

尝试类似:

ObjectStateEntry state = context.ObjectStateManager.GetObjectStateEntry(entity);
state.ChangeState(EntityState.Unchanged);

答案 1 :(得分:0)

实际上,EntityFramework会跟踪所有已修改的属性,但似乎byte []是一个例外,它只是不可逆转地标记为已更改。 我找到了一篇关于EF跟踪的文章:http://code.msdn.microsoft.com/How-to-undo-the-changes-in-00aed3c4 我通过不改变byte []属性解决了这个问题(因为我可以负担得起,因为它只用于序列化,可以推迟到实际保存到数据库之前)而不是更改,只将对象标记为已修改这似乎是工作:

                if(context.Entry(o).State == EntityState.Unchanged)
                {
                    context.Entry(o).State = EntityState.Modified;
                }