流畅的NHibernate一对多插入/删除问题

时间:2009-12-15 09:57:28

标签: nhibernate 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语句系列。我在这里做错了什么?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

您的选择因为Any调用而被解雇,该调用正在迭代一个延迟加载的集合,并在每个项目上加载。

如果你真的需要迭代那个集合,那么你要么忍受延迟加载和选择,要么你急于加载它。

答案 2 :(得分:0)

显然,Profile对象存储在Web Session中,nHibernate Session存储在Items中,因此Profile自然会被分离并且正在更新,它也会更新其子节点,从而触发集合的完全重新加载。

解决方案是在每个请求上重新加载Profile。