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

fro*_*sty 1 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

asg*_*las 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
Run Code Online (Sandbox Code Playgroud)

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

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

编辑: 上面的代码改为实际工作的东西,现在测试.很抱歉重命名实体和集合.我为我的测试项目稍微重命名了一下.