2010-10-04 3 views
11

Я пытаюсь выяснить, почему NHibernate обрабатывает каскадирование один-ко-многим (используя cascade = all-delete-orphan), как он это делает. Я столкнулся с той же проблемой, как этот парень:Почему NHibernate не удаляет сирот сначала?

Forcing NHibernate to cascade delete before inserts

Насколько я могу сказать, NHibernate всегда выполняет вставки, а затем обновления, а затем удаляет. Для этого может быть очень веская причина, но я не могу для жизни понять, что это за причина. Я надеюсь, что лучшее понимание этого поможет мне придумать решение, которое я не ненавижу :)

Есть ли хорошие теории в этом поведении? В каком сценарии лишение сирот сначала не будет работать? Все ли ОРМ работают таким образом?

+1

Просто хочу добавить свое разочарование в этот вопрос. В этом случае NHibernate является абсолютной ошибкой. Я весь день боролся с этой глупой проблемой. Даже самые простые ORM обрабатывают это намного более изящно, чем NHibernate. Я закончил тем, что должен был полностью прописать это.Мы с тобой оба что-то пропустили. – JasonCoder

ответ

2

EDIT: После того, как вы сказали, что нет причин, вот причина. Допустим, у вас есть следующий сценарий:

public class Dog { 
    public DogLeg StrongestLeg {get;set;} 
    public IList<DogLeg> Legs {get;set; 
} 

Если вы должны были удалить первый, и позволяет сказать, что вы удалите все Dog.Legs, то вы можете удалить StrongestLeg, который будет вызывать ссылочный нарушение. Следовательно, вы не можете УДАЛИТЬ, прежде чем вы ОБНОВЛЯЕТСЯ.

Допустим, вы добавили новую ногу, и эта новая нога также является StrongestLeg. Затем вы должны ВСТАВИТЬ перед обновлением, чтобы нога имела идентификатор, который можно вставить в Dog.StrongestLegId.

Итак, вы должны ВСТАВИТЬ, ОБНОВИТЬ, а затем УДАЛИТЬ.

Также как nHibernate основан на Hibernate, я взглянул на Hibernate и обнаружил, что несколько человек говорили о той же проблеме.

А вот лучший ответ от них:

Gail Badner добавил комментарий - 21/Feb/08 2:30 PM: Проблема возникает, когда к коллекции добавляется новый объект ассоциации с сгенерированным идентификатором . Первый этап при объединении объекта , содержащего эту коллекцию, составляет cascade сохранить новую ассоциацию объект. Каскад должен произойти до другие изменения в коллекции. Поскольку уникальный ключ для этого нового объекта связи совпадает с объектом , который уже сохраняется, ConstraintViolationException - . Это ожидаемое поведение.

+0

Это не только этот случай. В принципе, любой объект, на который делается ссылка, не может быть удален до тех пор, пока он не будет разыменован. Любой объект, который ссылается на другой, не может быть обновлен до тех пор, пока другой не будет вставлен. – Iain

+0

Некоторые РСУБД позволяют отложить проверку ограничений до конца транзакции, поэтому это не разумный вопрос и очень действительный и распространенный сценарий. Дополнительная информация http://stackoverflow.com/questions/1330020/is-it-possible-to-defer-referential-integrity-checks-until-the-end-of-a-transact – ironstone13

Смежные вопросы