我会尽量保持这种简洁,但希望不要错过我遇到的任何重要信息。我相信的代码提供了所有细节,但我遗漏了噪音(这是VB,所以有很多噪音:))。
“案例”对象有许多“作业”:
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
最后,Fluent NHibernate Mappings:
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映射术语中的“key-many-to-one”相关联。
当我为一个案例添加作业时,一切都很好,但当我删除引用时,我会遇到两个问题之一。使用此代码:
aCase.Assignments.Remove(someAssignment)
caseRepository.Save(aCase)
我得到的错误是,“无法删除集合行...无法将值NULL插入列'CaseId',表'CaseAssignments';列不允许空值.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试图: DELETE FROM CaseAssignments WHERE RoleId = [valid guid] AND CaseId = NULL
我一直在搜索线程和论坛以及NHibernate和Hibernate文档,并且还没有真正遇到类似的东西。希望这很简单。感谢任何对此拍摄的人!
答案 0 :(得分:9)
前几天我遇到了同样的问题。解决方案是在CaseMapping类的CaseAssignments集合中将“inverse”属性设置为“true”。像这样:
HasMany(Function(x) x.Assignments).KeyColumn("CaseId").Cascade.AllDeleteOrphan().Inverse()
据我所知,你必须同时将AllDeleteOrphan级联类型和Inverse属性设置为true才能生效。
我希望它有效!