我的存储库中有以下方法。这工作正常,我的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;
}
}
答案 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();
遗憾的是,尚未对此进行测试,我稍后可以这样做。 我们的想法是创建一个多查询,一次性获取所有需要的实体(可能不是最有效的数据库查询,但它至少只有一次),然后让会话从两个结果中拼接出实际的图形集。
一个稍微不同的用例在我当前的项目中运行良好,但我有点不确定我在这里展示的是否完全正确。但我会回答那个:)
修改强> 上面的代码改为实际工作的东西,现在已经过测试。 很抱歉重命名实体和集合。我为我的测试项目略微重命名了。