2012-03-19 5 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

관련 문제