2012-03-19 31 views
6

我試圖在ASP.NET MVC 2應用程序中實現搜索功能。我創建基於用戶輸入的條件表達式:Linq Expression中的條件運算符導致NHibernate異常

public ViewResult FindCustomer(string forename, string familyname, DateTime? dob) 
    { 
    Expression<Func<Customer, bool>> searchCriteria = p => (
                  forename.IsNullOrEmpty() ? true : p.Forename == forename 
                  && familyname.IsNullOrEmpty() ? true : p.FamilyNames.Any(n => n.Name == familyname) 
                  && dob.HasValue ? true : p.DOB == dob 
                  ); 

然後把它傳遞給方法在庫

IQueryable<Customer> customers = CustomerRepository.FilterBy(searchCriteria); 

問題是,當我運行此我得到下面的異常

System.InvalidCastException: Unable to cast object of type 'NHibernate.Hql.Ast.HqlCast' to type 'NHibernate.Hql.Ast.HqlBooleanExpression' 

根據this問題是在表達式中使用條件運算符。

所以我想我必須創建表達式的其他方式,但我不知道如何做到這一點。我對Linq很新,所以任何幫助都會被感激地接受!

回答

9

動態創建您的查詢呢?像這樣:

var customers = CustomerRepository.AllEntities(); 

if (!forename.IsNullOrEmpty()) 
    customers = customers.Where(p => p.Forename == forename); 
if (!familyname.IsNullOrEmpty()) 
    customers = customers.Where(p => p.FamilyNames.Any(n => n.Name==familyname)); 
if (dob.HasValue) 
    customers = customers.Where(p => p.DOB == dob); 

我不知道這是否有效,但我認爲這可能會更有效率。

+0

工作!非常感謝。我一直試圖避免寫這樣的東西,因爲我想避免多次調用數據庫,所以我認爲我需要構造一個包含所有參數的表達式。使用你的解決方案只執行一條SQL語句。這是NHibernate的一個功能嗎?它從多個LINQ表達式構建一條SQL語句以最大限度地減少對數據庫的調用?我想我需要更多地瞭解NHibernate和LINQ! – Babakoto 2012-03-20 11:29:53

+1

@Babakoto這是LINQ的一項功能。只有在您的'IQueryable'鏈的末尾調用'ToList'或'SingleOrDefault'(或類似的)方法之後,您的查詢纔會被評估,因此您可以動態地爲查詢添加任何過濾器。在顯式調用後,查詢處理器(如NHibernate)會將整個查詢鏈轉換爲SQL表達式。 – 2012-03-20 11:46:19

+0

太好了。再次感謝您的幫助 – Babakoto 2012-03-20 11:57:17