Fluent NHibernate一对多插入/删除问题

发布于 2024-08-15 02:01:10 字数 954 浏览 3 评论 0原文

我试图从映射为 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仲春光 2024-08-22 02:01:10

如果你想NHibernate删除孤儿使用级联模式all-delete-orphan

 mapping.HasMany<Artist>(x => x.Artists)
            .KeyColumn("User")
            .Inverse()
            .Cascade.AllDeleteOrphans();

If you want to NHibernate to delete orphans use cascade mode all-delete-orphan

 mapping.HasMany<Artist>(x => x.Artists)
            .KeyColumn("User")
            .Inverse()
            .Cascade.AllDeleteOrphans();
旧夏天 2024-08-22 02:01:10

您的选择由于您的 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.

夏末的微笑 2024-08-22 02:01:10

显然,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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文