2

编辑: 存根实体定义

我有两种实体类型SubscriberAddOn

它们在数据模型中的定义如下

订阅者(#SubscriberID ,名称,AddOnID)

AddOn( #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,subscriber); ”。

为什么会出现这种行为?

4

2 回答 2

3

在 EF 3.5 SP1 中,您无法在不知道原始值的情况下修改引用(即subscriber.Addon)。请注意,如果您使用 FK 关联,此限制将在 EF 4 中消失。

现在大部分时间 EF 对您隐藏了这种额外的复杂性,但当您像这样使用 Attach 时不会。

这是您需要的代码:

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 的缺点是它向数据库发出查询。

因此,像上面那样附加原始值只是节省了额外的查询。

希望这可以帮助

-亚历克斯

项目经理实体框架团队。

有关更多信息,请参阅我的 EF 技巧系列的技巧 26 。

于 2009-10-03T00:45:21.147 回答
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();
}
于 2009-10-02T21:58:15.437 回答