2013-07-29 32 views
1

在NHibernate中,下面的工作完全正常:NHibernate ISession.QueryOver()不能推斷類型,但ISession.Get()可以..這是爲什麼?

Session.Get(repoType.ToString(), id)) 

但這:

Session.QueryOver(repoType.ToString(), func) 

出於某種原因,其實不然。從文檔,這兩種方法需要在實體作爲一個字符串作爲第一個參數的名稱,但QueryOver與以下錯誤消息抱怨:

The type arguments for method 'NHibernate.ISession.QueryOver<T>(string, System.Linq.Expressions.Expression<System.Func<T>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. 

我相當肯定,這是由第一所致參數傳遞給QueryOver(entityName參數),而不是func參數。

爲什麼ISession.Get可以從給定的實體名稱推斷實體類型,但ISession.QueryOver不能?

回答

1

這不是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); 

但是,爲了便於閱讀,我寧願保留泛型參數。

+0

謝謝,我非常關注這些約定,我從真正的問題中分心了,這是func參數。我不能放入泛型類型參數的原因是我使用動態類型,但不久前我發現我可以使用「dynamic」關鍵字來聲明一個對象具有動態類型,而編譯器不會不再抱怨了(可能是繞過該對象的類型安全的一種方式)。當我輸入以下內容時,我遇到了另一個問題:Session.QueryOver(repoType.ToString(),()=> func).List(),它返回一個List of System.Func (contd ..) – Anshul

+0

(... contd),這是func變量的類型。那麼我怎樣才能得到它返回一個列表(所有將返回實現IRepository的對象),或者甚至是一個列表? – Anshul

+0

@Anshul - 我會說你不能使用QueryOver。但QueryOver是底層Criteria API的一個包裝。所以調用's.CreateCriteria(「myEntityName」)',然後調用'ICriteria.List' –

相關問題