好的,每当我遇到这种情况时,我都来回挣扎,直到我找到解决问题的方法(这通常不是我希望解决的方法)。
我所说的是EF中断开的实体,它们应该更新数据库中的现有实体。
我将在这里给出一个我的问题的例子(这个例子是我最后一次遇到这个导致我写这个问题的问题)。
我有一个使用Entity Framework的WCF服务。已为我的服务添加服务引用的其他程序已正常获取实体的代理版本。
案例是服务的使用者现在构造此代理类的对象,并在WCF服务上调用方法UpdateEntity。此实体具有指向其他类型实体的外键,并且我要将此新实体链接到的实体的主键也作为参数发送到此方法。在这种情况下,我希望更新数据库中具有相同主键的实体。看起来很简单吧?
我的方法现在看起来像这样:
public bool ChangeEntity(MyEntity entity, int otherTableForignKey)
{
//first I verify that the entity to update exist in the system
var entitytochange = entityContext.MyEntities.FirstOrDefault(e => e.Name == entity.Name);
if (systemtochange == null) return false;
try
{
entity.ForignEntity = entityContext.ForeignEntities.FirstOrDefault(f => f.Key == otherTableForignKey);
//code for updating the entity should go here, but I'm nor sure what
entityContext.SaveChanges();
return true;
}
catch (Exception exc)
{
return false;
}
}
我尝试了ApplyCurrentValues
,Attach
的许多不同组合,将ObjectState
设置为已修改等等,但我收到的错误消息是我无法添加新实体与现有实体相同的密钥,无法添加新对象的对象状态等等。
所以我的问题是:如果不编写看起来像大黑客的代码,最好的方法是什么。
我现在唯一可行的方法就是手动设置entitytochange
的属性entity
属性,但这是一个糟糕的解决方案,因为MyEntity
添加了任何属性如果我不记得在这个方法中添加代码,那么会破坏代码,而且似乎应该有另一种更好的方式。
修改
当我将entityContext.MyEntities.ApplyCurrentValues(entity);
放在我的评论上面时,我在此行中收到以下异常:
The existing object in the ObjectContext is in the Added state. Changes can only be applied when the existing object is in an unchanged or modified state.
但是,如果我在entity.ForignEntity = entityContext.ForeignEntities.FirstOrDefault(f => f.Key == otherTableForignKey);
上方删除此行,则ApplyCurrentValues
可以正常运行。
为什么我要将对象的ForeignEntity设置为Added状态?所以似乎在Detached实体上设置一个Property,将它附加到具有添加状态的上下文?