2010-11-05 2 views
4

Мне интересно, какой лучший дизайн будет для продолжения нового дочернего объекта с NHibernate без случайной перезаписи родителя в базе данных.NHibernate: Как сохранить новый объект без перезаписи родителя:

У меня есть проблема в том, что ребенок лицо будет выглядеть примерно так:

class Child 
{ 
    Parent Parent; 
    // other fields 
} 

Моя проблема заключается в том, что ребенок был подан из слоя пользовательского интерфейса вместе с идентификатором родителя, и это означает, что что Parent ref в основном не инициализирован: у него будет ID, но все остальное будет нулевым, потому что единственный способ заполнить его поля - это дополнительная поездка в базу данных, чтобы прочитать их.

Теперь, если я вызываю Session.SaveOrUpdate(child) на NHibernate, что произойдет с родителем. Я не хочу, чтобы NHibernate выполнял каскад, за исключением неинициализированного родителя, поскольку это просто уничтожило бы данные в базе данных. Как люди подходят к этой проблеме? Любые лучшие практики?

ответ

0

Если ваши модели выглядит следующим образом

class Parent 
{ 

} 


class Child 
{ 
    Parent myParent; 
} 

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

Вы можете попробовать это:

session.Lock(child.myParent, LockMode.None); 

перед сохранением, это должно сказать NHibernate, что нет никаких изменений в родительском объекте сохраняются, и он должен смотреть только на объекте для Id сохраняться связь между Родитель и ребенок

1

Вы должны, вероятно, работать с агрегированным корнем (возможно, с родителями) при выполнении Сэйвы (или SaveOrUpdates и т. Д.).

Почему не просто:

  • Fetch родительский объект, используя идентификатор родительского вас в ребенка из слоя UI
  • Добавьте ребенка родителей детей 'коллекции
+0

OK спасибо.Это будет означать дополнительную обратную связь с базой данных для получения родительского элемента, хотя я не собираюсь ничего делать с родительскими данными, чего я бы предпочел избежать. Нет лучшего способа избежать этого? – PhantomDrummer

+0

Используйте Load() как Trygve, чтобы избежать загрузки ненужных данных. – UpTheCreek

+1

Похоже, что происходит то, что дети заселяются непосредственно в пользовательский интерфейс по запросу без какого-либо отношения к родительскому. Предлагается общий принцип дизайна, в котором у вас никогда не бывает детей за пределами родителя. Вы, конечно, не добавляете новых детей, не проходя через родителя. – Sisyphus

3

Вы должны использовать session.Load (parentid) для получения совокупного корня. В отличие от метода session.Get(), это фактически не извлекает данные из базы данных, а просто создает объект родительского прокси, используемый для добавления дочерних объектов в правильный родительский элемент в БД (например, правильно введите внешний ключ) ,

Ваш код будет вероятно выглядеть примерно так:

// Set the Parent to a nhibernate proxy of the Parent using the ParentId supplied from the UI 
childFromUI.Parent = Session.Load<Parent>(childFromUI.Parent.Id); 
Session.Save(childFromUI); 

This article explains Get/Load and the nhibernate caches really well

+0

+1; интересную ссылку, но я нашел http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx более краткими ссылками на различия в Get vs Load. – Marijn

+0

Интересно, спасибо – PhantomDrummer

1

Я думаю, вам необходимо просмотреть конфигурацию отображения для nhibernate. Если вы определили по ссылке дочернего элемента родительскому элементу, который должен выполнить Cascade all, он обновит его! Итак, если вы скажете Cascade.None он ничего не сделает. Все остальные - плохие идеи. Потому что у вас уже есть информация этого родителя. Так зачем читать из db агана ?!

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