2009-10-31 69 views
1

如果我的Order实体具有OrderDetails列表,我可以使用NHibernateUtil.Initialize(Order.Details)轻松加载详细信息以及顺序。所以显然NHibernate拥有所有的信息来生成sql语句。 但是,如何在不手动创建条件的情况下查询数据库的详细信息(类似于Entity Framework中的CreateSourceQuery)? 有没有像NHibernateUtil.GetList(Order.Details)?在NHibernate中重新加载关联/相关集合

更新: 使用Darin的答案,这是我最终结束了。这是通用的,我可以则会使用Criteria APIHQL落实到实体基类

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 

回答

1

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

例如,如果您有一个客户实体加载名为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>(); 

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

+0

谢谢。这正是我所期待的。我从来没有想过使用过滤器。我其实一直在做查询(你的第二个例子)。 – 2009-11-03 09:19:06

1

查询NHibernate的对象的推荐方式。你有什么理由反对这两种方法吗?

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

UPDATE:

如果您想要只载入该协会没有加载,你可以使用下面的查询父对象:

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

我希望能够创造条件,采取实体的通用方法的HQL,它的关联路径,并返回关联列表(在本例中为OrderDetails)。使用createCriteria我将不得不指定限制Order.ID = xx。我认为NHibernate已经有了这些信息,我想知道是否有相当于Entity Framework的CreateSourceQuery方法。 – 2009-10-31 12:54:17

+0

一旦获得'Order'的实例,您只需使用关联'order.OrderDetails'来获取详细信息。 – 2009-10-31 13:04:53

+0

谢谢Darin。我想我可以用这个。 – 2009-10-31 14:37:00

1

为什么不直接加载顺序和访问其详细信息集合?如果您只能加载集合,则无法添加到集合中,因为关系需要订单。

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

+0

我刚刚使用NHibernateUtil.Initialize来说明我需要的查询类型。在我的情况下,我已经加载了Order和相关的Details,但是会做出更改,要求我重新加载Details。我可以轻松创建一个条件重新加载Order和Details(使用SetFetchMode),但我需要一种方法来获取Details。我希望已经有了一个函数或者简单的方法来获得这个,而不需要重新创建NHibernate已经拥有的信息。 – 2009-10-31 12:59:00

+0

你可以扩展为什么你需要重新加载细节?如果您需要选择数据库更改(如触发器操作),则可以调用ISession.Refresh()或在新的ISession中重新加载Order。 – 2009-10-31 13:40:10

+0

是的,触发器会导致更改。我所要做的只是获取细节,因为在这种情况下,我知道这些是唯一的更改,然后将其手动合并回Order.Details。在另一个会话中刷新或重新载入命令将会执行多余的数据获取(它会加载命令和其他未更改的关联),因为在这种特殊情况下只会更改细节。 – 2009-11-03 09:17:00