考虑以下简化域:
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
,列Id
和MovieId
。还有一个从MovieDetail.MovieId
到Movie.Id
的外键。
我们已经在NHibernate中映射了这一切,但是当获得Movie
个实例的集合时,我们想要一个带有MovieDetail
的左外连接。如果没有,我们在迭代Movie
个实例时可能会遇到N + 1问题。现在就是这种情况:对Movie.MovieDetail
属性的每次调用都有一个单独的查询。
我已尝试one-to-one
映射,但这似乎适用于同时拥有这两个实例的情况。在我们的例子中,我们并不总是MovieDetail
。此外,它们不共享相同的主键。
我研究了公式,但这需要我制作MovieDetail
工具IUserType
,基本上将NHibernate放入我的域名。我想避免这种情况。
答案 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
可能包含Description
,ReleaseDate
,Actors
等属性。我真的不明白为什么要将这些概念分开。通过将它们组合在一起,每次想要列出电影时,您可以减少1张桌子和1张FK加入。
该组件允许您将数据隔离到单独的实体,同时映射到与Movie
相同的表。