2010-09-03 20 views
7

Sto tentando di creare una clausola not in con l'API dei criteri NHibernate utilizzando NHLambdaExtensions. Leggendo la documentazione sono stato in grado di attuare la clausola di in facendoCome faccio ad esprimere "non in" usando lambdas?

.Add(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 })) 

Tuttavia, quando ho avvolgo intorno SqlExpression.Not ottengo l'errore

Error 5 The best overloaded method match for 'NHibernate.LambdaExtensions.SqlExpression.Not<oms_dal.Models.Zone>(System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>)' has some invalid arguments 
Error 6 Argument '1': cannot convert from 'NHibernate.Criterion.ICriterion' to 'System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>' 

sto usando questo pezzo di codice

.Add(SqlExpression.Not<Zone>(SqlExpression.In<Zone>(x => zoneAlias.ZoneId, new int[] { 1008, 1010 }))) 

Come posso realizzare questo? Utilizzando l'API regolare Criteri ero in grado di fare questo

.Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 }))) 

risposta

1

Non hanno lavorato con il criterio direttamente (io di solito uso Linq2NH), ma sembra che non solo vuole un lambda booleana, quindi non si può dare un altro criterio Questo può funzionare, anche se ho visto NH hanno problemi con membri di matrice in lambda:

.Add(SqlExpression.Not<Zone>(z=>new[]{1008,1010}.Contains(z.ZoneId)) 

EDIT: merda. Quello che sta succedendo qui è che il framework non sta effettivamente utilizzando il lambda, quindi mentre questo compila, il framework non lo chiama mai nel processo di esecuzione della query. Esamina invece in modo riflessivo l'MSIL del tuo delegato, esegue il reverse engineering della tua espressione lambda e la converte in una stringa per il comando SQL. Ovviamente, questo è un processo piuttosto complesso che i progettisti cercano di semplificare specificando suggerimenti su cosa stai facendo (in questo caso il tipo di SqlExpression che hai dichiarato) e cercando modelli per identificare il processo. In questo caso, tuttavia, anche a causa dei suggerimenti, la struttura non ha idea di cosa si stia tentando di fare.

Se il traduttore dietro valutare Not() clausole non possono indovinare lo scopo di loop logici o chiamate di metodo, si può ben essere bloccato con

.Add(SqlExpression.Not<Zone>(z=>z.ZoneId == 1008 
           || z.ZoneId == 1010)) 

chissà ho dovuto ridursi espressioni in questo modo per Linq2NHibernate per funzionare correttamente.

+0

corretta, che vuole un lambda booleano. Usando il tuo codice, NH ora dice 'Impossibile determinare il tipo di membro da nuovo [] {1008, 1010} .Contains (z.ZoneId)' quando eseguo la query. – Mike

+0

Il nuovo codice fornito ora fornisce sempre l'errore "Impossibile determinare il membro da ...". La soluzione più semplice e più brutta che riesca a pensare è semplicemente fare '.Add (SqlExpression.Not (() => zoneAlias.ZoneId == 1008))' per tutto. – Mike

2

Utilizzando il vecchio mondo con le lambda sembra funzionare:

.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 })); 
Problemi correlati