2012-03-19 24 views
6

Bir ASP.NET MVC 2 uygulamasında arama işlevselliğini uygulamaya çalışıyorum. Ben kullanıcı tarafından girilen kriterlere dayalı bir ifade oluşturun:Linq Expression'daki koşullu işleç, NHibernate istisnasına neden oluyor

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 
                  ); 

sonra Depodaki bir yönteme geçirilen

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

sorun bu çalıştırdığınızda aşağıdaki özel durum alıyorum olduğunu

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

this'a göre sorun, ifadedeki koşullu işlevin kullanılmasıdır.

Bu yüzden, İfadeyi başka bir şekilde oluşturmam gerektiğini varsayalım ama nasıl yapacağımı bilmiyorum. Linq için oldukça yeniyim, bu yüzden herhangi bir yardım minnetle kabul edilirdi!

cevap

9

Sorgununuzu dinamik olarak oluşturmaktan ne haber? Bunun gibi:

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); 

Bunun işe yarayıp yaramadığını bilmiyorum ama bunun daha verimli olabileceğini düşünüyorum.

+0

Bu işe yarıyor! Çok teşekkürler. Böyle bir şey yazmaktan kaçınmaya çalışıyorum çünkü veritabanına çoklu çağrılardan kaçınmak istedim, böylece tüm parametreleri içeren tek bir ifade oluşturmam gerektiğini düşündüm. Çözümünüzü kullanmak sadece tek bir SQL ifadesi yürütür. Bu bir NHibernate özelliği mi? Veritabanına yapılan çağrıları en aza indirmek için birden çok LINQ ifadesinden bir SQL deyimi oluşturur? Hem NHibernate hem de LINQ hakkında daha fazla şey öğrenmem gerektiğini düşünüyorum! – Babakoto

+1

@Babakoto Bu, LINQ'un bir özelliğidir. Sorgunuz 'IQueryable' zincirinizin sonunda' ToList' veya 'SingleOrDefault' (veya benzeri) yöntemini çağırıncaya kadar değerlendirilmeyecek, böylece sorgunuza dinamik olarak herhangi bir filtre ekleyebilirsiniz. Açık bir çağrıdan sonra sorgu işlemcisi (NHibernate gibi) tüm sorgu zincirini bir SQL ifadesine dönüştürecektir. –

+0

Bu harika. Yardımınız için tekrar teşekkürler. – Babakoto

İlgili konular