Fluent NHibernate一对多插入/删除问题
我试图从映射为 .HasMany() 的列表中添加和删除元素,但是 nHibernate 在这个简单的场景中执行一些奇怪的查询:
if (Profile.Artists.Any(x => x.Artist == artist))
{
Profile.Artists.Remove(Profile.Artists.Single(x => x.Artist == artist));
}
else
{
Profile.Artists.Add(new Artist { Artist = artist, User = User.Current.ID });
}
此方法是在事务中执行的。我得到的是整个集合的一系列 SELECT 语句:
SELECT ... WHERE artis0_.User=?p0;?p0 = 5
等等,然后 nHibernate 尝试首先更新 Profile,然后更新 Artists。尽管艺术家实际上只能被删除或插入(注意:使用 Inverse() 艺术家只能被插入而不能被删除)。
UPDATE user_profile SET UserFK = ?p0 ...
UPDATE user_artists SET User = null WHERE User = ?p0 AND User = ?p1 AND Artist = ?p2;?p0 = 5, ?p1 = 5, ?p2 = 16
映射是这样完成的:
mapping.HasMany<Artist>(x => x.Artists)
.KeyColumn("User")
.Inverse()
.Cascade.All();
这对我来说没有任何意义,尤其是一系列 SELECT 语句。我在这里做错了什么?
I am trying to add and remove elements from a list mapped as .HasMany(), but nHibernate executes some weird queries on this simple scenario:
if (Profile.Artists.Any(x => x.Artist == artist))
{
Profile.Artists.Remove(Profile.Artists.Single(x => x.Artist == artist));
}
else
{
Profile.Artists.Add(new Artist { Artist = artist, User = User.Current.ID });
}
This method is executed withing a transaction. What I get is a series of SELECT statements for the whole collection:
SELECT ... WHERE artis0_.User=?p0;?p0 = 5
And so on, and then nHibernate tries to update Profile first and Artists second. Though Artists can really only be either deleted or inserted (note: with Inverse() Artists only get inserted and never deleted).
UPDATE user_profile SET UserFK = ?p0 ...
UPDATE user_artists SET User = null WHERE User = ?p0 AND User = ?p1 AND Artist = ?p2;?p0 = 5, ?p1 = 5, ?p2 = 16
Mapping is done like this:
mapping.HasMany<Artist>(x => x.Artists)
.KeyColumn("User")
.Inverse()
.Cascade.All();
None of this makes any sense to me, especially the series of SELECT statements. What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果你想NHibernate删除孤儿使用级联模式all-delete-orphan
If you want to NHibernate to delete orphans use cascade mode all-delete-orphan
您的选择由于您的
Any
调用而被触发,该调用正在迭代一个延迟加载的集合,加载每个项目。如果您确实需要迭代该集合,那么您要么接受它的延迟加载并进行选择,要么急切地加载它。
Your selects are being fired because of your
Any
call, which is iterating a lazy-loaded collection loading each item as it goes.If you really need to iterate that collection, then you either live with it being lazy-loaded and having the selects, or you eager load it.
显然,Profile 对象存储在 Web Session 中,而 nHibernate Session 存储在 Items 中,因此 Profile 自然会分离并正在更新,这也更新了其子项,触发集合的完全重新加载。
解决方案是简单地根据每个请求重新加载配置文件。
Apparently the Profile object was stored in the web Session and the nHibernate Session was stored in the Items, so naturally the Profile became detached and was being updated, which also updated its children, triggering the full reload of the collection.
The solution was to simply reload Profile on each request.