Pregunta

Estoy intentando crear una cláusula not in con la API Criterios NHibernate usando NHLambdaExtensions. La lectura de la documentación que era capaz de poner en práctica la cláusula in haciendo

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

Sin embargo, cuando se envuelve alrededor de SqlExpression.Not consigo el error

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>>'

Estoy usando este pedazo de código

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

¿Cómo puedo lograr esto? Uso de la API Criterios regulares que era capaz de hacer esto

.Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 })))
¿Fue útil?

Solución

¿No han trabajado con criterio directamente (generalmente uso Linq2NH), pero parece que no quiere simplemente una lambda booleano, por lo que no se puede dar otro criterio. Esto puede funcionar, aunque he visto NH tener problemas con miembros de la matriz en lambdas:

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

EDIT: basura. Lo que está pasando aquí es que el marco no es en realidad el uso de la lambda, así que mientras Esto compila, el marco en realidad nunca lo llama en el proceso de ejecución de la consulta. En su lugar, está examinando reflexivamente el MSIL de su delegado, ingeniería inversa de su expresión lambda y convertir eso a una cadena para el comando SQL. Eso es, obviamente, un proceso bastante complejo que los diseñadores tratan de simplificar al tener que especifique pistas acerca de lo que está haciendo (en este caso el tipo de EnunciadoSql OperadorCompatible EnunciadoParamétricoOConstante se declaró) y en busca de patrones para identificar el proceso. En este caso, sin embargo, incluso teniendo en cuenta los consejos, el marco no tiene idea de lo que estás tratando de hacer.

Si el traductor detrás de la evaluación No () cláusulas no se puede adivinar el propósito de bucles lógicos o las llamadas de método, que puede muy bien estar pegado a

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

Dios sabe que he tenido que reducen las expresiones de esta manera por Linq2NHibernate funcione correctamente.

Otros consejos

Uso del viejo mundo con las lambdas parece funcionar:

.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top