2012-03-19 7 views
6

Sto tentando di implementare la funzionalità di ricerca in un'applicazione ASP.NET MVC 2. Creo un'espressione sulla base di criteri immessi dall'utente:L'operatore condizionale in Espressione Linq causa l'eccezione 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 
                  ); 

che poi viene passato a un metodo nella repository

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

Il problema è quando ho eseguito questo ottengo la seguente eccezione

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

Secondo this il problema è l'uso dell'operatore condizionale nell'espressione.

Quindi suppongo di dover creare l'espressione in un altro modo ma non sono sicuro di come farlo. Sono abbastanza nuovo a Linq quindi qualsiasi aiuto sarebbe accettato con gratitudine!

risposta

9

Che ne dici di creare dinamicamente la tua query? Mi piace:

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

Non so se questo funziona, ma penso che questo potrebbe essere più efficiente.

+0

Questo funziona! Grazie mille. Stavo cercando di evitare di scrivere qualcosa del genere perché volevo evitare più chiamate al database, quindi pensavo di aver bisogno di costruire una singola espressione contenente tutti i parametri. L'utilizzo della soluzione esegue solo una singola istruzione SQL. È una caratteristica di NHibernate? Costruisce un'istruzione SQL da più espressioni LINQ per ridurre al minimo le chiamate al database? Penso di aver bisogno di saperne di più su NHibernate e LINQ! – Babakoto

+1

@Babakoto Questa è una funzionalità di LINQ. La tua query non verrà valutata finché non chiami un metodo 'ToList' o' SingleOrDefault' (o simile) alla fine della tua catena 'IQueryable', così puoi aggiungere dinamicamente filtri alla tua query. Dopo una chiamata esplicita, il processore di query (come NHibernate) trasformerà l'intera catena di query in un'espressione SQL. –

+0

È grandioso. Grazie ancora per il tuo aiuto – Babakoto