键多对一和键属性关联:nhibernate 不会从集合中删除项目
我会尽量保持简洁,但希望不会在我的麻烦中错过任何重要信息。我相信代码提供了所有细节,但我忽略了噪音(它是 VB,所以有很多噪音:))。
一个“Case”对象有许多“Assignments”:
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 与“key-many-”相关。 XML 映射术语中的“to-one”。
当我向案例添加作业时,一切都很好,但是当我删除引用时,我遇到两个问题之一。使用此代码:
aCase.Assignments.Remove(someAssignment)
caseRepository.Save(aCase)
我得到的错误是,“无法删除集合行...无法将 NULL 值插入列“CaseId”、表“CaseAssignments”;列不允许空值。更新失败。 该语句已终止。”这是由于尝试发出以下 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 文档,但还没有真正遇到类似的东西。希望这很简单。感谢任何尝试这个的人!
I'll try to keep this terse, but hopefully won't miss any important information in my troubles. The code I believe provides all details, but I've left out the noise (it's VB, so there's lots of noise :) ).
A "Case" object has many "Assignments":
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
The data model I've been handed looks about like what you'd expect, except CaseAssignment is a composite key:
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
Finally, the 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 correlates with "key-many-to-one" in the XML mapping lingo.
When I add assignments to a case all is good, but when I remove references I get one of two problems. With this code:
aCase.Assignments.Remove(someAssignment)
caseRepository.Save(aCase)
The error I get back is, "Could not delete collection rows... Cannot insert the value NULL into column 'CaseId', table 'CaseAssignments'; column does not allow nulls. UPDATE fails.
The statement has been terminated." This was from trying to issue the following 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] **!?!**
So that's a little messed up. So I try this code:
aCase.Assignments.Remove(someAssignment)
someAssignment.Case = Nothing
caseRepository.Save(aCase)
and the error is "Unexpected row count: 0; expected: 1" because NHibernate tried to:
DELETE FROM CaseAssignments WHERE RoleId = [valid guid] AND CaseId = NULL
I've been scouring threads and forums and the NHibernate and Hibernate docs and haven't really come across anything similar yet. Hopefully it's something simple. Thanks to anyone who takes a shot at this one!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
几天前我也遇到了同样的问题。解决方案是在 CaseMapping 类中的 CaseAssignments 集合上将“inverse”属性设置为“true”。像这样:
据我所知,您必须将 AllDeleteOrphan 级联类型和 Inverse 属性设置为 true 才能正常工作。
我希望它有效!
I had the same problem a few days ago. The solution is to put the "inverse" attribute to "true" on your collection of CaseAssignments in your CaseMapping class. Like this:
As far as I know, you must have both the AllDeleteOrphan cascade type AND the Inverse property set to true for this to work.
I hope it works!