在M:N关系上设置all-delete-orphan时,NHibernate无法检测其他关联的问题 [英] Problem with NHibernate not detecting other associations when all-delete-orphan is set on a M:N relationship

查看:92
本文介绍了在M:N关系上设置all-delete-orphan时,NHibernate无法检测其他关联的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是场景:

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

I have 3 objects called Person, VideoGame, and Store.

一个人可以拥有许多电子游戏

One Person can have many VideoGames

一个VideoGame可以属于多个人

One VideoGame can belong to many Persons

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

Same M:N relationship is between Store and VideoGames

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

In the DB, the only thing besides these entities are two simple join tables PersonsVideoGames and StoresVideoGames.

假设所有内容都具有Id属性,并且它们是唯一的.

Assume everything has an Id property and they are unique.

业务规则:

  • 不希望视频游戏出现在VideoGames表中如果它与任何事物都没有关联(一个孤儿)
  • 如果它与至少一个其他对象
  • 相关联,我愿意将其放在表中
  • 您不是直接管理VideoGames,而是由其他方面(商店,人员)管理保存/删除视频游戏.
  • I do not want a video game to be in the VideoGames table if it is not associated with anything (an orphan)
  • I do want it in the table if it associated with at least one other object
  • You do not manage VideoGames directly, rather the other sides (Store, Person) manage saving/deleting video games.

使用NHibernate映射可以做到吗?从我实际的项目实现来看,它似乎在基本的Person<-> VideoGame级别上不起作用.

Is this possible to do using NHibernate mapping? From my actual project implementation, it doesn't seem to work at the basic Person <-> VideoGame level.

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

NHibernate currently will delete the VideoGame even though it is still associated with other Persons (it is not truly an orphan).

我的映射如下:

人员 已将VideoGame的M:N设置为一组,并启用了层叠样式的all-delete-orphan.

Person Has M:N of VideoGame as a set, with cascade style all-delete-orphan enabled.

视频游戏 启用了M:N个人设置,并启用了延迟加载,逆向和级联样式保存更新.

VideoGame Has M:N of Person as a set, with lazy-load, inverse, and cascade style save-update enabled.

此人没有其VideoGames属性的公共设置器.它具有如下功能:

The Person does not have a public setter for its VideoGames property. It has a function like so:

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

然后,每当保存一个Person时,我都会获得一个视频游戏列表(已有的或全新的),然后使用该设置方法:

Then whenever I save a Person, I get a list of video games (either existing already or brand new), then use that set method:

' 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"等,然后在数据库中找到与该Person 相匹配的任何现有视频游戏,或创建一个新的具有该简短标题的域对象(假定只有Id和ShortTitle是唯一的属性).

A video game can be referred to using a more friendly ID like "ShortTitle" as an example. The saving then takes in a IEnumerable(Of String) like "DA:O,BatmanAA,LBP2" etc. and then finds any existing video games in the DB for that Person that match it or creates a new domain object with that short title (assume only Id and ShortTitle are the only properties).

那么,有谁知道这是怎么回事?当NHibernate从某个视频游戏中删除某个VideoGame时,为什么它没有检测到该VideoGame已经与其他人相关联?

So, does anyone know what's wrong? How come NHibernate isn't detecting that a VideoGame is already associated with other Persons when it removes a VideoGame from that set?

此外,假设我已完成这项工作,那么一旦我建立了更多的M:N关系(例如商店),这种情况是否还能奏效?

Furthermore, assuming I got this working, will this scenario even work once I set up more M:N relationships (like Stores)?

推荐答案

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

all-delete-orphan is not that powerful. If you have other relationships, you have to manage delete cascading manually.

这篇关于在M:N关系上设置all-delete-orphan时,NHibernate无法检测其他关联的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆