NHibernate: Как сохранить новый объект, не перезаписывая родительский объект: - PullRequest
4 голосов
/ 05 ноября 2010

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

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

class Child
{
    Parent Parent; 
    // other fields
}

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

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

Ответы [ 4 ]

3 голосов
/ 05 ноября 2010

Вы должны использовать 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);

В этой статье очень хорошо объясняются Get / Load и кэши nhibernate

1 голос
/ 08 июня 2012

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

1 голос
/ 05 ноября 2010

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

Почему бы просто:

  • Получить родительский объект, используя родительский идентификатор, который у вас есть в дочернем элементе из слоя пользовательского интерфейса
  • Добавить ребенка в коллекцию детей родителей
0 голосов
/ 07 ноября 2010

Если ваши модели выглядят так

class Parent 
{

}


class Child
{
     Parent myParent;
}

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

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

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

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

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