渴望用NHibernate加载可选的一对一

时间:2013-05-14 14:42:31

标签: nhibernate mapping one-to-one select-n-plus-1

考虑以下简化域:

public class Movie
{
    public virtual int Id { get; set; }
    public virtual MovieDetail MovieDetail { get; set; }
}

public class MovieDetail
{
    public virtual int Id { get; set; }
    public virtual Movie Movie { get; set; }
}

如果没有MovieDetail,则Movie不能存在,但Movie可能不存在MovieDetail(即我们没有关于它的详细信息)。

我们的数据库有一个单独的Movie表,列Id,另一个表MovieDetail,列IdMovieId。还有一个从MovieDetail.MovieIdMovie.Id的外键。

我们已经在NHibernate中映射了这一切,但是当获得Movie个实例的集合时,我们想要一个带有MovieDetail的左外连接。如果没有,我们在迭代Movie个实例时可能会遇到N + 1问题。现在就是这种情况:对Movie.MovieDetail属性的每次调用都有一个单独的查询。

我已尝试one-to-one映射,但这似乎适用于同时拥有这两个实例的情况。在我们的例子中,我们并不总是MovieDetail。此外,它们不共享相同的主键。

我研究了公式,但这需要我制作MovieDetail工具IUserType,基本上将NHibernate放入我的域名。我想避免这种情况。

2 个答案:

答案 0 :(得分:0)

也许您可以尝试在Movie映射到MovieDetail中添加多对一关系,它将作为一对一映射。

当您将选项'not-null'设置为“false”时,我认为它也可以为空。 我不知道你是否在延迟加载,如果是这样的话,MovieDetail在需要时被加载而不是由左连接构造加载。

两个类中的所有属性都不应该是虚拟的吗?

<many-to-one name="MovieDetail" column="Id" class="MovieDetail" not-null="false" lazy="false"/>

答案 1 :(得分:0)

我有点急,我不知道你是否可以修改你的域/数据库架构,但你可能想看看http://ayende.com/blog/3937/nhibernate-mapping-component

在我看来,Movie最多只能有一个MovieDetail可能不存在。 MovieDetail可能包含DescriptionReleaseDateActors等属性。我真的不明白为什么要将这些概念分开。通过将它们组合在一起,每次想要列出电影时,您可以减少1张桌子和1张FK加入。

该组件允许您将数据隔离到单独的实体,同时映射到与Movie相同的表。