Come si esprimo “non in” utilizzando lambda?
-
30-09-2019 - |
Domanda
Sto cercando di creare una clausola not in
con l'API Criteri NHibernate utilizzando NHLambdaExtensions. Leggendo la documentazione sono stato in grado di attuare la clausola di in
facendo
.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 fare questo? Utilizzando l'API regolare Criteri ero in grado di fare questo
.Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 })))
Soluzione
non hanno lavorato con il criterio direttamente (io di solito uso Linq2NH), ma sembra che non vuole semplicemente un lambda booleana, quindi non si può dare un altro criterio. Questo può funzionare, anche se ho visto NH avere problemi con i membri di matrice in lambda:
.Add(SqlExpression.Not<Zone>(z=>new[]{1008,1010}.Contains(z.ZoneId))
EDIT: merda. Che cosa sta succedendo qui è che il quadro non è in realtà utilizzando lambda, così mentre questa compilazione, il quadro in realtà mai lo chiama nel processo di esecuzione della query. E 'invece riflessivo esaminando la MSIL del delegato, reverse-engineering la vostra espressione lambda e la conversione che in una stringa per il comando SQL. Questo è, ovviamente, un processo piuttosto complesso che i progettisti cercano di semplificare avendo specificato suggerimenti su ciò che si sta facendo (in questo caso il tipo di SqlExpression si dichiarò) e alla ricerca di modelli per identificare il processo. In questo caso, però, anche visti i suggerimenti, il quadro non ha alcuna idea di cosa si sta cercando di fare.
Se il traduttore dietro valutare Not () clausole non possono divina 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.
Altri suggerimenti
Utilizzando il vecchio mondo con le lambda sembra funzionare:
.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));