Проблема с обновлением отношения сущностей с использованием заглушек сущностей - PullRequest
2 голосов
/ 02 октября 2009

РЕДАКТИРОВАТЬ: Определение объектов заглушки

У меня есть два типа сущностей Подписчик и AddOn

Их определение в модели данных:

Подписчик ( # SubscriberID , Имя, AddOnID)

аддон ( # AddOnID , Имя)

Столбец AddOnID в таблице Subscriber ссылается на столбец AddOnID в таблице AddOn.


Я пытаюсь обновить ссылку AddOn определенного объекта Subscriber. Допустим, я хочу изменить ссылку AddOn подписчика # 1 на 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); " OR " context.Refresh (RefreshMode.ClietWins , подписчик);"после операторов присоединения заставляет вещи работать.

Почему это поведение?

Ответы [ 2 ]

3 голосов
/ 03 октября 2009

В EF 3.5 SP1 вы не можете изменить ссылку (то есть subscriber.Addon), не зная исходного значения. Обратите внимание, что это ограничение исчезнет в EF 4, если вы используете FK Ассоциации .

Теперь в большинстве случаев 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 является то, что он отправляет запрос обратно в базу данных.

Таким образом, добавление исходного значения, как указано выше, просто сохраняет этот дополнительный запрос.

Надеюсь, это поможет

1020 * для -Alex- *

Руководитель программы Entity Framework Team.

См. Совет 26 из моей серии EF Tips для получения дополнительной информации.

0 голосов
/ 03 октября 2009

Я думаю, вы спрашиваете, как добавить дочернюю сущность в другую сущность. Итак, в вашем случае у вас есть родительский объект: подписчик и дочерний объект: 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();
}
...