nhibernate:如何初始化子列表对象

时间:2010-05-15 18:23:13

标签: nhibernate nhibernate-mapping

我的存储库中有以下方法。这工作正常,我的orderItems按预期初始化,但orderItems包含另一个名为OrderItemAddress的集合。这些都没有初始化。我该怎么做?

public Model.Order Get(int id)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        Model.Order order = session
            .CreateCriteria(typeof(Model.Order))
            .Add(Restrictions.Eq("Id", id))
            .UniqueResult<Model.Order>();

        NHibernateUtil.Initialize(order.OrderItems);
        return order;
    }
}

1 个答案:

答案 0 :(得分:5)

首先,您可能只想使用连接向数据库服务器发出一个查询,而不是在获取订单后初始化集合,如下所示:

public Model.Order Get(int id)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        Model.Order order = session
            .CreateCriteria(typeof(Model.Order))
            .Add(Restrictions.Eq("Id", id))
            .SetFetchMode("OrderItems", FetchMode.Join)
            .UniqueResult<Model.Order>();

        return order;
    }
}

另一件事是急切地加载一系列集合而不会严重影响性能。在你的场景中,这样做的一种方法是:

var orderCriteria = DetachedCriteria.For<Order>()
    .SetFetchMode("OrderLines", FetchMode.Eager)
    .Add(Restrictions.Eq("Id", orderId));

var orderLinesCriteria = DetachedCriteria.For<OrderLine>()
    .CreateAlias("Order", "order")
    .SetFetchMode("Addresses", FetchMode.Eager)
    .Add(Restrictions.Eq("order.Id", orderId));

IList list = s.CreateMultiCriteria()
    .Add(orderCriteria)
    .Add(orderLinesCriteria)
    .List();

var order = ((IList)list[0]).Cast<Order>().First();

遗憾的是,尚未对此进行测试,我稍后可以这样做。 我们的想法是创建一个多查询,一次性获取所有需要的实体(可能不是最有效的数据库查询,但它至少只有一次),然后让会话从两个结果中拼接出实际的图形集。

一个稍微不同的用例在我当前的项目中运行良好,但我有点不确定我在这里展示的是否完全正确。但我会回答那个:)

修改 上面的代码改为实际工作的东西,现在已经过测试。 很抱歉重命名实体和集合。我为我的测试项目略微重命名了。