1

如果我有带有 OrderDetails 列表的 Order 实体,我可以使用 NHibernateUtil.Initialize(Order.Details) 轻松加载详细信息以及订单。所以很明显NHibernate拥有生成sql语句的所有信息。但是如何在不手动创建条件的情况下仅查询数据库的详细信息(类似于实体框架中的 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
4

3 回答 3

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>();
于 2009-10-31T12:33:17.397 回答
1

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

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

于 2009-10-31T12:34:17.083 回答
1

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

例如,如果您有一个名为 customer 的 Customer 实体已加载,该实体具有名为 Orders 的 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)

于 2009-11-01T22:59:59.530 回答