我似乎无法从断开连接的 poco 对象更新我的数据库。在此示例中,我获取了一个 ApplicationUser 对象,更新了 varchar(100) 字段 SSOID,但没有任何更改生效。即使我在保存方法中重新获取对象,也不会向数据库发送任何内容。
如果我尝试调用 ApplyCurrentValues,它会抛出
在 ObjectStateManager 中找不到其键与所提供对象的键匹配的对象。验证提供的对象的键值是否与必须应用更改的对象的键值相匹配。
public void Save(ApplicationUser au)
{
ApplicationUser original = context.ApplicationUsers.FirstorDefault(a => a.UserID == au.UserID);
context.ContextOptions.ProxyCreationEnabled = false; //changing this has no effect
if(original == null)
{
context.AddObject("ApplicationUsers",au); //this works!
}
else
{
///let's manually set some properties on the object I just fetched.
original.SSOID = au.SSOID;
ObjectStateEntry entry = null;
context.DetectChanges();
context.ObjectStateManager.TryGetObjectStateEntry(original.EntityKey, out entry);
//entry is still null!
context.ApplicationUsers.ApplyCurrentValues(original); //BOOM!!
}
context.SaveChanges();
return;
}
我尝试了所有我能想到的方法,甚至让 ApplicationUser
实现了 System.Data.Objects.DataClasses.IEntityWithKey
,这应该是不必要的。
这是映射:
<EntitySetMapping Name="ApplicationUsers">
<EntityTypeMapping TypeName="MyCompanyName.ApplicationUser">
<MappingFragment StoreEntitySet="ApplicationUser">
<ScalarProperty Name="UserID" ColumnName="UserID" />
<ScalarProperty Name="SystemID" ColumnName="SystemID" />
<ScalarProperty Name="Username" ColumnName="Username" />
<!--snip-->
<ScalarProperty Name="CreatedOn" ColumnName="CreatedOn" />
<ScalarProperty Name="CreatedBy" ColumnName="CreatedBy" />
<ScalarProperty Name="SSOID" ColumnName="SSOID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
最佳答案
您使用的是直接/简单的 POCO T4 template , 或自跟踪实体模板??
直接的 POCO 不支持任何更改跟踪 - 如果您需要,您需要自跟踪实体。
查看资源:
更新:我认为您已经非常接近正确的做事方式了。您重新加载对象的原始状态(我可能会添加对时间戳或其他内容的检查,以确保存储中的对象在此期间没有被更改)。
完成后,我相信您只需要检测自己发生了什么变化/au
和 original
之间存在哪些差异;相应地更新 original
,然后只需调用 context.SaveChanges()
。
据我所知,.DetectChanges()
无法工作,因为您使用的是直接的 POCO 类,没有任何更改跟踪,例如您的 au
对象没有任何方式知道发生了什么变化——您基本上需要自己进行逐个属性的比较。
关于entity-framework - EF 4.0 POCO 魔术不起作用——未检测到任何更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3924823/