2009-10-31 34 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