【问题标题】:key-many-to-one and key-property association: nhibernate won't DELETE items from set键多对一和键属性关联:nhibernate 不会从集合中删除项目
【发布时间】:2009-10-09 03:34:24
【问题描述】:

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

最后,流畅的 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';列不允许空值。更新失败。 该语句已终止。”这是由于尝试发出以下 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] AND CaseId = NULL

我一直在搜索线程和论坛以及 NHibernate 和 Hibernate 文档,但还没有真正遇到任何类似的东西。希望这很简单。感谢任何对此进行尝试的人!

【问题讨论】:

    标签: nhibernate fluent-nhibernate composite-id


    【解决方案1】:

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

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

    据我所知,您必须将 AllDeleteOrphan 级联类型和 Inverse 属性都设置为 true 才能工作。

    我希望它有效!

    【讨论】:

    • 同上 Groxx,但对于使用非复合键的更简单的情况。
    猜你喜欢
    • 2011-01-17
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 2011-06-27
    • 1970-01-01
    相关资源
    最近更新 更多