Отслеживание внешнего ключа структуры объекта вызывает проблему - PullRequest
2 голосов
/ 01 июня 2011

работа с EF4, первый подход к модели в VS 2010:

Рассмотрим следующую модель EntityModel:

"OrderBase" - это абстрактная сущность с одним свойством "Name"

«Detail» (с одним свойством «Text») - это объект, который имеет многозначную ассоциацию с «OrderBase» (т. Е. Один OrderBase имеет несколько деталей)

«Comment» (с одним свойством «Text») - это объект, который имеет многозначную связь с «OrderBase» (т. е. один OrderBase имеет несколько комментариев)

«MusicOrder» - это объект, производный от «OrderBase» с одним свойством «Количество» (int)

"SongOrder" - это объект, производный от "OrderBase" только с одним свойством "Length" (int).SongOrder имеет отношение один к одному с MusicOrder (т. Е. Один MusicOrder имеет несколько SonOrders)

Для краткого обзора: хотел опубликовать изображение datamdel, но я не позволил ... Так что любые вопросы, касающиесямодель данных.

Итак, теперь я генерирую свою базу данных, выполняю сценарий ddl и пытаюсь запустить следующий код:

using (DataContainer container = new DataContainer())
{
    MusicOrder musicOrder = new MusicOrder{Name = "Oldies", Quantity = 1};
    SongOrder songOrder = new SongOrder {Name = "Great balls of fire", Length = 240};
    songOrder.Details.Add(new Detail{Text = "Song from Jerry Lee Lewis"});
    songOrder.Comments.Add(new Comment{Text = "Cool song"});

    container.OrderBaseSet.AddObject(songOrder); //relevant line
    musicOrder.SongOrders.Add(songOrder);

    songOrder.Details.Clear();
    songOrder.Comments.Clear();
    container.OrderBaseSet.AddObject(musicOrder);
    container.SaveChanges();
}

В этом случае «SaveChanges» приводит к исключению, сообщающему мне что-тоо пропущенных отношениях внешнего ключа ...

Но если я переместу строку

container.OrderBaseSet.AddObject(songOrder);

после части "Очистить", в результате получится следующий код:

using (DataContainer container = new DataContainer())
{
    MusicOrder musicOrder = new MusicOrder{Name = "Oldies", Quantity = 1};
    SongOrder songOrder = new SongOrder {Name = "Great balls of fire", Length = 240};
    songOrder.Details.Add(new Detail{Text = "Song from Jerry Lee Lewis"});
    songOrder.Comments.Add(new Comment{Text = "Cool song"});

    musicOrder.SongOrders.Add(songOrder);

    songOrder.Details.Clear();
    songOrder.Comments.Clear();

    container.OrderBaseSet.AddObject(songOrder); //relevant line
    container.OrderBaseSet.AddObject(musicOrder);
    container.SaveChanges();
}

все работает отлично.

Как вы можете видеть, я знаю, как обойти исключение, и я знаю, что нет смысла "дважды добавлять" SongOrder.Но мне интересно, это ошибка или особенность.Почему исключение брошено в моем первом примере.Был бы очень признателен за исчерпывающее объяснение.На мой взгляд, структура сущностей также должна быть в состоянии справиться с первым примером и не создавать исключения.Так что я бы сказал, что это ошибка.

Не стесняйтесь комментировать;)

Andi

Ответы [ 2 ]

1 голос
/ 01 июня 2011

Это происходит потому, что вызов AddObject добавляет не только одну сущность, но и все связанные сущности, которые также не привязаны к контексту.Поэтому, когда вы звоните AddObject(songOrder) в первом примере, вы также добавляете Detail и Comment.Но после этого вы вызываете Remove в свойствах навигации, чтобы удалить Detial и Comment.Remove на присоединенных объектах только разорвет отношение, но не удалит Detail и Comment из контекста (это только установит их основное отношение на ноль), поэтому, как только вы попытаетесь вызвать SaveChanges, оно взорвется, потому чтоВы пытаетесь сохранить Detail и Comment без связанных OrderBase (я думаю, что отношения не равны nullalbe).

Во втором примере Comment и Detail удаляются перед добавлением заказа вконтекст, поэтому он ведет себя так, как ожидалось.

Это не ошибка, это «фича».

1 голос
/ 01 июня 2011

вам не нужно добавлять композицию на базу.просто добавьте песню в музыку, а затем музыку в базу.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...