сопоставление ключ-многие-к-одному и свойство-ключ: nhibernate не удаляет элементы из набора - PullRequest
4 голосов
/ 09 октября 2009

Я постараюсь сохранить это вкратце, но, надеюсь, не упущу ни одной важной информации в моих неприятностях. Код, который я считаю, предоставляет все детали, но я не учел шум (это VB, поэтому много шума :)).

Объект "Case" имеет много "Назначений":

Public Class Case
  Property CaseId As Guid 
  Property Assignments As ISet(Of CaseAssignment)
End Class

Public Class CaseAssignment
  Property Case As Case
  Property RoleId As Guid
End Class

Модель данных, которую мне передали, выглядит примерно так, как вы ожидаете, за исключением того, что CaseAssignment является составным ключом:

table Case
   CaseId uniqueid not null primary key
   ...

table CaseAssignment
   CaseId uniqueid not null
   RoleId uniqueid not null
   PK := (CaseId, RoleId)
   FK from CaseId -> Case.CaseId

Наконец, беглые отображения NHibernate:

Class CaseMapping
  Public Sub New()
    Table("Case")
    KeyColumn("CaseId")
    HasMany(Function(x) x.Assignments).KeyColumn("CaseId").Cascade.AllDeleteOrphan()
End Class

Class CaseAssignmentMapping
  Public Sub New()
    Table("CaseAssignment")
    CompositeId() _
      .KeyReference(Function(x) x.Case, "CaseId") _
      .KeyProperty(Function(x) x.RoleId)
End Class

KeyReference коррелирует с "ключ-многие-к-одному" в языковой таблице XML.

Когда я добавляю назначения к делу, все хорошо, но когда я удаляю ссылки, у меня возникает одна из двух проблем. С этим кодом:

aCase.Assignments.Remove(someAssignment)
caseRepository.Save(aCase)

Я получаю сообщение об ошибке: «Не удалось удалить строки коллекции ... Невозможно вставить значение NULL в столбец« CaseId », таблица« CaseAssignments »; в столбце не допускаются значения NULL. UPDATE завершается ошибкой. Оператор был прерван. "Это было из-за попытки выпустить следующий SQL:

UPDATE CaseAssignments SET CaseId = null
WHERE CaseId = @p0 AND RoleId = @p1 AND CaseId = @p2
@p0=[valid guid #1],
@p1=[valid guid #2],
@p2=[valid guid #1 again] **!?!**

Так что это немного запутано. Поэтому я пытаюсь этот код:

aCase.Assignments.Remove(someAssignment)
someAssignment.Case = Nothing
caseRepository.Save(aCase)

и ошибка «Неожиданное количество строк: 0; ожидаемое: 1», потому что NHibernate попытался: УДАЛИТЬ ИЗ CaseAssignments, ГДЕ RoleId = [действительный guid] И CaseId = NULL

Я обыскивал темы и форумы, а также документы NHibernate и Hibernate и пока ничего подобного не встречал. Надеюсь, это что-то простое. Спасибо всем, кто делает снимок!

1 Ответ

9 голосов
/ 13 января 2010

У меня была такая же проблема несколько дней назад. Решение состоит в том, чтобы присвоить атрибуту «инверсия» значение «true» в вашей коллекции CaseAssignments в вашем классе CaseMapping. Как это:

HasMany(Function(x) x.Assignments).KeyColumn("CaseId").Cascade.AllDeleteOrphan().Inverse()

Насколько я знаю, у вас должен быть установлен как каскадный тип AllDeleteOrphan, так и свойство Inverse в true, чтобы это работало.

Я надеюсь, что это работает!

...