我有两种实体类型 Subscriber 和 AddOn
他们在数据模型中的定义如下
订阅者( #SubscriberID ,名称,AddOnID)
附加组件(的 #AddOnID 下,名称)
Subscriber表中的AddOnID列引用AddOn表中的AddOnID列。
我正在尝试更新特定订阅服务器实体的AddOn引用。 可以说,我想将Subscriber#1的AddOn引用更改为AddOn#5。这是代码:
Subscriber subscriber = new Subscriber { SubscriberID = 1};
AddOn newAddOn = new AddOn { AddOnID = 5};
using (var context = new TestEntities())
{
context.AttachTo("AddOn", newAddOn);
context.AttachTo("Subscriber", subscriber);
subscriber.Name = "dummy";
subscriber.AddOn = newAddOn;
context.SaveChanges();
}
这会在“ context.SaveChanges(); ”
行中引发异常正在从AssociationSet'FK-Subscriber-AddOn'添加或删除关系。对于基数约束,还必须添加或删除相应的“订阅者”。
当我注释掉“ subscriber.AddOn = newAddOn; ”行时,更新操作正常。
那么,为什么我不能像更新非引用属性一样更新引用属性?
注意:我不知道它是否是正确的方法,但添加“ context.Refresh(RefreshMode.StoreWins,subscriber); ”或“ context.Refresh(RefreshMode。 ClietWins,订阅者); “在附加语句之后使事情有效。
为什么会出现这种情况?
答案 0 :(得分:3)
在EF 3.5 SP1中,您无法在不知道原始值的情况下修改引用(即subscriber.Addon)。请注意,此限制将在EF 4 if you use FK Associations中消失。
现在,大部分时间EF都会向您隐瞒这种额外的复杂性,但是当您使用像这样的附加时则不行。
以下是您需要的代码:
AddOn newAddOn = new AddOn { AddOnID = 5};
AddOn oldAddOn = new AddOn { AddOnID = 4}; // you need to remember the old id.
Subscriber subscriber = new Subscriber { SubscriberID = 1, AddOn = oldAddOn};
using (var context = new TestEntities())
{
context.AttachTo("AddOn", newAddOn);
context.AttachTo("Subscriber", subscriber); // will attach the oldAddOn too
subscriber.Name = "dummy";
subscriber.AddOn = newAddOn;
context.SaveChanges();
}
正如您所看到的,我们只是告诉EF关于原始关系,然后像以前一样更改它。
那应该解决你的问题。
正如您发现调用refresh也有效...因为它为您从数据库中获取了引用的原始值。使用Refresh的缺点是它会将查询发回数据库。
因此,如上所述附加原始值只会保存额外的查询。
希望这有帮助
-Alex
项目经理实体框架小组。
有关详细信息,请参阅my EF Tips series的提示26。
答案 1 :(得分:0)
我想您正在询问如何将子实体添加到另一个实体。因此,在您的情况下,您拥有父实体:订阅者和子实体:AddOn。 如果是这种情况,并且您的数据模型具有正确的关系设置,那么您可能需要以下代码:
Subscriber subscriber = new Subscriber { SubscriberID = 1};
AddOn newAddOn = new AddOn { AddOnID = 5};
using (var context = new TestEntities())
{
context.AttachTo("Subscriber", subscriber);
subscriber.Addon.Add(newAddOn);
subscriber.Name = "dummy";
context.SaveChanges();
}