假设我有一个名为MyItem的实体。它可以包含在许多“父母”中,例如SomeCollection和SomeOtherCollection。因为它可以包含在许多父母中,并且因为我不希望MyItem知道父母,所以我想在MyItem中没有引用父母的任何属性。
因为像SomeCollection这样的父母可以包含许多MyItems,所以我觉得我需要在从父母那里获取孩子时需要某种分页。这将使我无法在SomeCollection中引用MyItems的属性。懒惰是否加载,它总是“全有或全无”(对吧?)。
我确实需要在MyItem实体和它们的父级之间使用一些引用,但是以数据库中的映射表的形式。
问题:
答案 0 :(得分:1)
<强> Many-to-One 强>
父包含属性Child,孩子可能与多个父母链接。
class Parent
{
public virtual MyItem Child { get; set; }
}
<class name="Parent">
<many-to-one name="Child" column="MyItemId" />
</class>
<强> Many-to-Many with a join table 强>
父母包含一系列儿童,儿童可能与几个父母有联系。
class Parent
{
public virtual IList<MyItem> Children { get; set; }
}
<class name="Parent">
<bag name="Children" table="parent_myitem">
<key column="parentid" />
<many-to-many class="MyItem" column="MyItemId" />
<bag>
</class>
// find Parent with child named "foo".
DetachedCriteria.For<Parent>()
.CreateAlias("Child", "c")
.Add(Restrictions.Eq("c.Name", "foo"));
// find Parent with particular child
DetachedCriteria.For<Parent>()
.Add(Restrictions.Eq("Child", child ));
// find Parent with one of children named "foo".
DetachedCriteria.For<Parent>()
.CreateAlias("Children", "c")
.Add(Restrictions.Eq("c.Name", "foo"));
// find a "page" of children for a parent
DetachedCriteria.For<Parent>()
.Add(Restrictions.Eq("Id", parent.Id ))
.CreateAlias("Children", "c")
.SetFirstResult( 1041 )
.SetMaxResults( 20 )
.GetExecutableCriteria( session )
.List<MyItem>();
通过在第一次访问时使用延迟加载整个子集合,然后在后续“页面”上索引到它,可以或可以不更有效地完成最后一个查询。这取决于您的数据和使用情况。
除非我先前知道儿童收藏品是巨大的,否则我会先去懒惰的载重路线。如果时间和profiling显示出严重的缓慢,那么我会切换到Criteria方法。
答案 1 :(得分:0)
< class name="ConfigurationDomain" table="configuration"> < property name="ProjectId" column="project_id" type="int" insert="false" update="false" /> < property name="UserId" column="user_id" type="int" insert="false" update="false" /> < many-to-one name="Project" column="project_id" lazy="false" /> < many-to-one name="User" column="estimator_id" lazy="false" /> < /class>
< class name="UserDomain" table="user"> < set name="ConfigurationList" lazy="true" cascade="all-delete-orphan"> < key column="user_id" /> < one-to-many class="ConfigurationDomain" /> < /set> < /class> < class name="ProjectDomain" table="user"> < set name="ConfigurationList" lazy="true" cascade="all-delete-orphan"> < key column="project_id" /> < one-to-many class="ConfigurationDomain" /> < /set> < /class>
就像那样,它对我有用。如何访问ID为55的用户的配置是这样的:
我不使用someUser.ConfigurationList,因为它很慢。我只映射父级,以便我可以在HQL中执行此操作(它更快):
select c from ConfigurationDomain c where c.UserId=55
要获得全局配置,我会这样做:
select c from ConfigurationDomain c where (c.UserId IS NULL) and (c.ProjectId IS NULL)
经过反思,我认为如果你决定使用HQL,你甚至可以删除集合映射。
注意:我在NHibernate的早期使用过Criteria,但后来我发现HQL对我来说有点强大,其他人可能对此有不同看法。