Вставка родителей и детей с помощью NHibernate одновременно - PullRequest
10 голосов
/ 19 августа 2011

Я пытаюсь сохранить (вставить) родительский объект со списком дочерних объектов.Обе стороны используют Guid в качестве первичных ключей.Ключи не могут быть обнуляемыми, и в БД не установлено отношение клавиш.

Сохранение не работает, выдано исключение, утверждающее, что я пытаюсь сохранить нулевой ключ во внешнем ключе РодителяДетский стол.

Я ожидал, что nhibernate создаст ключ для Родителя и сообщит об этом его дочерним объектам.Это ограничение NHibernate или использования Guids в качестве первичных ключей?

Этот ответ предполагает, что вам нужно установить родителя вручную, это действительно единственный способ?

Вот мои сопоставления для справки:

Родительское сопоставление:

HasMany(x => x.Children).KeyColumn("ParentKey").Inverse().Cascade.All();

Дочернее сопоставление:

 References(x => x.Parent).Not.Nullable().Column("ParentKey");

1 Ответ

15 голосов
/ 19 августа 2011

NHibernate не волшебство. Это всего лишь ORM, если ваши дети не имеют своей ссылки на родителя, почему он предполагает, что, поскольку у родителя есть список детей, на которые ссылаются дети, в свою очередь, ДОЛЖНА быть ссылка на родителя?

Я полагаю, что вы ответили на свой вопрос, когда заявили, что у дочерних сущностей не заполняется свойство Parent (что означает, что оно имеет значение null, что означает, что NHibernate будет пытаться сохранить нулевое значение для идентификатора Parent ваш детский стол).

Если бы вы использовали эти объекты БЕЗ NHibernate, имело бы смысл установить родительскую ссылку на дочерние объекты при их добавлении.

РЕДАКТИРОВАТЬ: Это для случая, когда вы указали 'Inverse' на вашем отображении. Если вы удалите этот вызов для 'Inverse,' , он должен работать так, как вы хотели, чтобы он работал, так как Inverse указывает, что другой конец (дочерний лицо) несет ответственность за отслеживание отношений. Это означает, что вам нужно вручную установить ссылку родителя на ребенка.

Однако удаление оператора Inverse приведет к сохранению дочернего элемента (ren), родительского элемента, а затем к родительскому идентификатору дочернего элемента (ren), который будет ОБНОВЛЕН. Поскольку у вас есть нулевое ограничение для родительского идентификатора, это означает, что он все равно не будет работать, так как он изначально вставит дочерний элемент с родительским идентификатором, равным нулю.

Два решения будут заключаться в том, чтобы либо удалить это ограничение, либо просто добавить в родительский метод метод с именем AddChild:

public void AddChild(Child childObj)
{
    childObj.Parent = this;
    Children.Add(childObj);
}

Добавить еще один метод с именем RemoveChild:

public void RemoveChild(Child childObj)
{
    if (Children.Contains(childObj))
    {
        Child.Parent = null;
        Children.Remove(childObj);
    }
}

Затем просто используйте эти методы для добавления / удаления потомков.

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