這不是nHibernate庫的問題,它是.NET泛型和Linq表達式的問題。
NHibernate可能能夠推斷出實體類型,但你必須先獲得代碼才能編譯。 :-)
爲QueryOver函數簽名如下:
IQueryOver<T, T> QueryOver<T>(string entityName, Expression<Func<T>> alias) where T : class;
注意,一個Func<T>
是不是同一類型的System.Linq.Expressions.Expression<T>
。
在你的例子中,我假設你已經聲明一個Func<T>
作爲一個單獨的變量,並且編譯器也無法弄清楚該怎麼投它。
以下是通話的一些變化:
// Defining the second parameter explicitly as an expression.
// This works
Company companyAlias = null;
System.Linq.Expressions.Expression < Func <Company>> expression =() => companyAlias;
var q1 = this.Session.QueryOver("Company", expression);
我們可以讓編譯器把一個在線拉姆達到表達。這也適用,編譯器推斷所有的類型參數。
var q2 = this.Session.QueryOver("Company",() => companyAlias);
如果我們使用普通函數對象而不是表達式,它將失敗。 在這裏,編譯器無法弄清楚如何使Func<Company>
適合通用表達式。因此,錯誤「類型參數不能被使用推斷......」
Func<Company> func =() => companyAlias;
var q3 = this.Session.QueryOver("Company", func);
我們通過明確說明類型幫助編譯器。下面的代碼仍然會失敗,但我們會得到一個更好的錯誤。 「的最好超載比賽......有一些無效參數」
var q4 = this.Session.QueryOver<Company>("Company", func);
如果可能的話,最好給它的類型作爲一般的表達,而不是名稱。這樣,如果您重命名類型但忘記更改函數中的字符串,則可以避免潛在的錯誤。
var q = session.QueryOver<Company>(() => companyAlias);
你甚至不需要在這種情況下放置泛型參數。
var q = session.QueryOver(() => companyAlias);
但是,爲了便於閱讀,我寧願保留泛型參數。
謝謝,我非常關注這些約定,我從真正的問題中分心了,這是func參數。我不能放入泛型類型參數的原因是我使用動態類型,但不久前我發現我可以使用「dynamic」關鍵字來聲明一個對象具有動態類型,而編譯器不會不再抱怨了(可能是繞過該對象的類型安全的一種方式)。當我輸入以下內容時,我遇到了另一個問題:Session.QueryOver(repoType.ToString(),()=> func).List(),它返回一個List of System.Func(contd ..) –
Anshul
(... contd),這是func變量的類型。那麼我怎樣才能得到它返回一個列表(所有將返回實現IRepository的對象),或者甚至是一個列表
@Anshul - 我會說你不能使用QueryOver。但QueryOver是底層Criteria API的一個包裝。所以調用's.CreateCriteria(「myEntityName」)',然後調用'ICriteria.List' –