0

这是场景:

我有 3 个对象,分别称为 Person、VideoGame 和 Store。

一个人可以拥有多个视频游戏

一个 VideoGame 可以属于多个 Person

Store 和 VideoGames 之间存在相同的 M:N 关系

在数据库中,除了这些实体之外,唯一的就是两个简单的连接表 PersonsVideoGames 和 StoresVideoGames。

假设所有东西都有一个 Id 属性并且它们是唯一的。

商业规则:

  • 如果视频游戏与任何内容(孤儿)无关,我希望视频游戏出现在 VideoGames 表中
  • 如果它与至少一个其他对象相关联,我确实希望它在表中
  • 您不直接管理 VideoGames,而是由其他方(商店、人员)管理保存/删除视频游戏。

使用 NHibernate 映射可以做到这一点吗?从我的实际项目实施来看,它似乎不适用于基本的 Person <-> VideoGame 级别。

NHibernate 当前将删除 VideoGame,即使它仍然与其他人相关联(它不是真正的孤儿)。

我的映射看起来像:

Person 将 VideoGame 的 M:N 作为一组,并启用了级联样式 all-delete-orphan。

VideoGame 具有 M:N 的 Person 作为一组,并启用了延迟加载、反向和级联样式保存更新。

Person 的 VideoGames 属性没有公共设置器。它有这样的功能:

Public Overridable Sub SetVideoGames(ByVal games As IEnumerable(Of VideoGame))
    If Me.VideoGames Is Nothing Then Exit Sub

    ' Add if the game isn't in the old list.
    For Each g In games
        If Not Me.VideoGames.Any(Function(g2) g2.Id = g.Id) Then
            Me.VideoGames.Add(usr)
        End If
    Next

    ' Remove if the game isn't in the new list
    For Each g In Me.VideoGames.ToList()
        If Not games.Any(Function(g2) g2.Id = g.Id) Then
            Me.VideoGames.Remove(g)
        End If
    Next
End Sub

然后,每当我保存一个人时,我都会得到一个视频游戏列表(现有的或全新的),然后使用该 set 方法:

' listOfVideogames is just a list of ShortTitle strings

Dim result As New List(Of VideoGame)()
Dim newGames As New List(Of VideoGame)()
Dim existingGames As IList(Of VideoGame) ' = Session.Get(blah, gets the existing games for this person)

' Add the existing games to the result set
result.AddRange(existingGames)

' Get any titles from the given list not in the existing list
For Each title In listOfVideogames.Except(existingGames.Select(Function(g) g.ShortTitle))
    Dim newGame As New VideoGame() With {
        .ShortTitle = title 
    }

    newGames.Add(newGame)
Next

' Add them to the resultset
result.AddRange(newGames)

existingPerson.SetVideoGames(result)
' Do other updates
MyNHibernateDataProvider.Save(existingPerson)

可以使用更友好的 ID(例如“ShortTitle”)来引用视频游戏。保存然后接受一个 IEnumerable(Of String) 像 "DA:O,BatmanAA,LBP2" 等,然后在数据库中找到匹配它的那个人的任何现有视频游戏,或者创建一个具有该短标题的新域对象 (假设只有 Id 和 ShortTitle 是唯一的属性)。

那么,有谁知道出了什么问题?当 NHibernate 从该集合中删除一个 VideoGame 时,它​​为什么没有检测到一个 VideoGame 已经与其他 Persons 相关联?

此外,假设我得到了这个工作,一旦我建立了更多的 M:N 关系(比如商店),这个场景甚至会工作吗?

4

1 回答 1

1

all-delete-orphan不是那么强大。如果您有其他关系,则必须手动管理删除级联。

于 2010-09-01T20:30:14.467 回答