在NHibernate中重新加载关联/相关集合

时间:2009-10-31 12:15:31

标签: nhibernate relationship

如果我的Order实体带有OrderDetails列表,我可以通过使用NHibernateUtil.Initialize(Order.Details)轻松地将详细信息与订单一起加载。显然NHibernate拥有生成sql语句的所有信息。 但是,如何在不手动创建条件的情况下仅查询数据库中的详细信息(类似于Entity Framework中的CreateSourceQuery)? 是否有类似NHibernateUtil.GetList(Order.Details)的东西?

更新: 使用达林的答案,我最终得到了。这是通用的,我可以在实体基类

中实现它
Dim entity as EntityBase
Dim queryString = String.Format("select entityAlias.{1} from {0} entityAlias where entityAlias.id = :ID", entity.GetType.Name, collectionPropertyName)
Dim query = Session.CreateQuery(queryString).SetParameter("ID", entity.ID)
Return query.List

3 个答案:

答案 0 :(得分:1)

在NHibernate中查询对象的推荐方法是使用Criteria APIHQL。你有任何理由反对这两种方法中的任何一种吗?

var details = session.CreateCriteria<OrderDetails>().List<OrderDetails>();
var details = session.CreateQuery("from OrderDetails").List<OrderDetails>();

更新:

如果您只想加载关联而不加载父对象,可以使用以下查询:

var details = session.CreateQuery(
        "select " + 
        "  orderDetail" + 
        "from " + 
        "  Order order," + 
        "  OrderDetail orderDetail " + 
        "where " + 
        "  orderDetail in elements(order.Details)"
    )
    .List<OrderDetail>();

答案 1 :(得分:1)

为什么不加载订单并访问其Details集合?如果您只能加载集合,则无法添加到集合中,因为关系需要订单。

我认为你误用了NHibernateUtil.Initialize。其目的是在特殊情况下强制初始化代理集合(延迟加载)。渴望加载与延迟加载相反;在那种情况下,集合将始终使用其父对象加载,并且不需要代理。如果您已经拥有Order对象,那么访问Details集合将导致它被加载。如果您想要预先获取,可以在映射选项中设置它。

答案 2 :(得分:1)

NHibernate有一个内置的方法来完成我认为你所要求的。 (ISession.CreateFilter)

例如,如果您有一个名为customer的Customer实体,其中包含一组名为Orders的订单,您可以通过执行此操作来加载订单。

var orderQuery = session.CreateFilter(customer.Orders, string.Empty);  
var orders = orderQuery.List<Order>();

这与以下内容相同,只是更清洁一点。

var orderQuery = session.CreateQuery("from orders o where o.Customer.id = :customerId")
                        .SetParameter("customerId", customer.Id);
var orders = orderQuery.List<Order>();

如果要过滤集合,可以将hql where子句作为第二个参数传递给ISession.CreateFilter(object, string)