2011-03-10 97 views
2

鑑於以下時,「不能在此泛型集合中使用」。
區域包含一系列產品對象。
任何給定的產品都有一個公司和一個區域。
SpecialProduct是Product的一個子類。HQL查詢結果返回一個子類

我在NHibernate中使用下面的HQL查詢。

// return all SpecialProperty objects for a given company and area. 
IQuery query = session.CreateQuery("select product from Company as company " + 
    "join company.Products as product " + 
    "join product.Area as area " + 
    "where company.Id = :coId " + 
    "and area.Id = :arId " + 
    "and product.class = MyNamespace.DomainModel.SpecialProduct ") 
    .SetInt64("coId", companyId) 
    .SetInt64("arId", areaId); 
IList<SpecialProduct> specialProducts = query.List<SpecialProduct>(); 

當上述執行第二份聲明,我得到一個錯誤,指出:

無法執行查詢[SQL:SQL不可] 值「SpecialProduct」的類型是MyNamespace.DomainModel」不。 SpecialProduct「並且不能用於這個通用集合。
參數名:價值

(注意對象顯示上面,因爲在SpecialProduct類的ToString()重寫的「SpecialProduct」在郵件中。)

如果我改變了語句返回一個列表超類,產品,像這樣......的

IList<Product> products = query.List<Product>(); 

...然後我沒有得到錯誤和單一的匹配對象在列表中返回。在調試器中檢查這個對象我發現這看起來實際上是一個根據ToString()重寫的SpecialProduct,但仔細觀察,我發現它是一個NHibernate代理類。如果我嘗試將該對象投射到SpecialProduct,則投射失敗。嗯...

我也檢查了數據庫本身,並確認該記錄保存爲一個SpecialProduct(基於事實,那就是在連接子類表中的匹配記錄)。

我需要得到結果作爲SpecialProperty對象的通用集合。

任何想法,爲什麼這不工作?

+0

問題突然消失。由於一些在代碼的其他地方的變化(在查詢中沒有變化),查詢現在返回的類的實例實際,而不是類的NHibernate的代理公司。去圖...這將是很好的知道**爲什麼**它開始返回實際的對象,而不是代理萬一發生這種情況再次發生。 :-S – MylesRip 2011-03-18 04:45:53

回答

0

這是設計。 NH代理從基類繼承而不是子類。

希望this link有幫助。

+0

感謝您的鏈接,迭戈。這是有道理的,代理從另一個對象遍歷使用引用的基本類型不能直接轉換爲子類型的屬性達到。然而,在我的情況下,引用在** HQL查詢中是**,這也限制了返回類型(「... product.class = subtype」)。換句話說,我向NH提供了足夠的信息,以便事先知道應該返回的類型。此外,我所要求的亞型作爲查詢(而不是引用它們的對象的列表)的結果列表。難道沒有辦法指導NH返回亞型嗎? – MylesRip 2011-04-05 18:46:00

+0

也許使用CreateCriteria來代替?像'session.CreateCriteria(typeof運算(SpecialProperty)....列表();'也許 – MylesRip 2011-04-05 18:48:31

+1

@MylesRip:否?。最好的情況下,它會工作*有時*(在那裏),只要你已經加載了會話的實例的代理,它就會慘敗。 – 2011-04-05 20:27:20