键多对一和键属性关联:nhibernate 不会从集合中删除项目

发布于 2024-08-07 09:22:38 字数 1920 浏览 3 评论 0原文

我会尽量保持简洁,但希望不会在我的麻烦中错过任何重要信息。我相信代码提供了所有细节,但我忽略了噪音(它是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空宴 2024-08-14 09:22:38

几天前我也遇到了同样的问题。解决方案是在 CaseMapping 类中的 CaseAssignments 集合上将“inverse”属性设置为“true”。像这样:

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

据我所知,您必须将 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:

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

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文