如果我的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
答案 0 :(得分:1)
在NHibernate中查询对象的推荐方法是使用Criteria API或HQL。你有任何理由反对这两种方法中的任何一种吗?
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)