2010-09-03 18 views
7

Estoy tratando de crear una cláusula not in con la API de criterios NHibernate utilizando NHLambdaExtensions. La lectura de la documentación que era capaz de poner en práctica la cláusula in haciendo¿Cómo expreso "no en" usando lambdas?

.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 esta pieza 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 }))) 

Respuesta

1

no ha 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 que NH tiene problemas con los miembros de array en lambdas:

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

EDIT: crap. Lo que está sucediendo aquí es que el framework no está realmente usando el lambda, por lo tanto, mientras esto se compila, el framework nunca lo llama en el proceso de ejecutar la consulta. En su lugar, examina reflexivamente el MSIL de tu delegado, realiza una ingeniería inversa de tu expresión lambda y la convierte en una cadena para el comando SQL. Esto es, obviamente, un proceso bastante complejo que los diseñadores intentan simplificar haciendo que especifiquen pistas sobre lo que está haciendo (en este caso, el tipo de SqlExpression que declaró) y buscando patrones para identificar el proceso. Sin embargo, en este caso, incluso teniendo en cuenta las sugerencias, 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 pueden adivinar el propósito de bucles lógicos o las llamadas de método, que bien puede ser pegado con

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

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

+0

correcta, que quiere una lambda booleano. Usando su código, NH ahora dice 'No se pudo determinar el tipo de miembro de nuevo [] {1008, 1010} .Contiene (z.ZoneId)' cuando ejecuto la consulta. – Mike

+0

El nuevo código provisto ahora siempre da el error "No se pudo determinar el miembro de ...". La solución más sencilla y fea que puedo pensar es simplemente hacer '.Add (SqlExpression.Not (() => zoneAlias.ZoneId == 1008))' para todo. – Mike

2

Uso del viejo mundo con las lambdas parece funcionar:

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