【问题标题】:Problem with updating entity relation using stub entities使用存根实体更新实体关系的问题
【发布时间】:2009-10-02 17:34:36
【问题描述】:

编辑: Stub Entities Definition

我有两种实体类型 SubscriberAddOn

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

订阅者(#SubscriberID,Name,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);" 后附加语句使事情正常进行。

为什么会这样?

【问题讨论】:

    标签: c# entity-framework reference relation


    【解决方案1】:

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

    现在大部分时间 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 也有效……因为它会为您从数据库中获取原始值以供参考。使用 Refresh 的缺点是它向数据库发出查询。

    所以像上面这样附加原始值只是保存了额外的查询。

    希望对你有帮助

    -亚历克斯

    项目经理实体框架团队。

    有关更多信息,请参阅my EF Tips series 的提示 26。

    【讨论】:

    • 就我而言,我唯一知道的是订阅者的 ID,我没有关于旧的 AddOnID 的信息。所以在 EF 3.5 中这种情况没有解决方案(没有额外的查询)对吧?
    • 如果您不知道旧的 id,您可以使用 Alex 提出的模式,但让 oldAddOn 的 id 类似于 -1。然后 EF 会看到您使用不同的 id 引用 newAddOn ...我不确定它是否会起作用,但我认为我会通过它作为一种可能性...
    【解决方案2】:

    我想您是在问如何将子实体添加到另一个实体。因此,在您的情况下,您有父实体:订阅者和子实体: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();
    }
    

    【讨论】:

    • 不,我不是在问添加。由于订阅者插件具有多对一的关系,因此数据源中存在的每个订阅者都必须定义一个插件。所以我需要的是外键更新。
    猜你喜欢
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多