【问题标题】:Eager loading an optional one-to-one with NHibernate渴望使用 NHibernate 加载可选的一对一
【发布时间】:2013-05-08 21:53:48
【问题描述】:

考虑以下简化域:

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; }
}

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

我们的数据库为Movie 提供了一个单独的表,其中包含Id 列,以及一个用于MovieDetail 的单独表,其中包含IdMovieId 列。从MovieDetail.MovieIdMovie.Id 还有一个外键。

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

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

我研究过公式,但这需要我让我的MovieDetail 实现IUserType,本质上是将 NHibernate 放入我的域中。我想避免这种情况。

【问题讨论】:

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


    【解决方案1】:

    也许您可以尝试在MovieMovieDetail 的映射中添加多对一关系,它将充当一对一映射。

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

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

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

    【讨论】:

    • 我无法让它工作。可能,我们的域有一些奇特的东西(我确实简化了它)。属性确实应该是虚拟的(它们是)。
    【解决方案2】:

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

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

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

    【讨论】:

    • 嗯,这是一个简化的域/模式。真实的事物有其原因,但我对其进行了简化/匿名化。
    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2013-08-03
    • 2016-01-10
    • 1970-01-01
    • 2013-05-06
    相关资源
    最近更新 更多