在M:N关系上设置all-delete-orphan时,NHibernate无法检测其他关联的问题 [英] Problem with NHibernate not detecting other associations when all-delete-orphan is set on a M:N relationship
问题描述
这是场景:
我有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屋!