2012-03-19 9 views
6

ASP.NET MVC 2アプリケーションで検索機能を実装しようとしています。私は、ユーザーが入力した基準に基づいて式を作成します。Linq式の条件演算子で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

+1

@BabakotoこれはLINQの機能です。 'IQueryable'チェーンの終わりに' ToList'や 'SingleOrDefault'(あるいは同様の)メソッドを呼び出すまでクエリは評価されないので、クエリにフィルタを動的に追加することができます。明示的な呼び出しの後、(NHibernateのような)照会プロセッサーは、照会チェーン全体をSQL式に変換する。 –

+0

それは素晴らしいです。あなたの助けをもう一度おねがいします。 – Babakoto