我试图找出如何让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,以便认为该对象是从数据库中检索到的,就像现在一样?
答案 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;
}