2009-08-26 6 views
12

Esto puede ser algo obvio, pero he estado golpeando mi cabeza contra él durante unas horas y no puedo entender dónde me estoy equivocando.NHibernate disjunction que da como resultado AND consultas en lugar de O

Estoy tratando de ejecutar un pequeño fragmento de código para probar la adición de criterios O a una consulta de NHibernate. Este es el código que tengo:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     criteria.Add(Restrictions.Disjunction().Add(criterion)); 
    } 

    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
} 

Es algo simple que yo esperaría que devolver todos los objetos de prueba con los ID de 1-3. Pero, cuando estoy ejecutando el código, la consulta generada es para encontrar un objeto con ID = 1 AND ID = 2 AND ID = 3. Lo cual, como era de esperar, no devuelve nada.

La asignación está configurada correctamente (puedo agregar/editar/eliminar/enumerar todos los objetos) y hay objetos allí con estos ID.

¿Estoy haciendo algo obviamente incorrecto? Todas las muestras de usar Disyunción que he visto en línea parecen usarlo de esta manera. Simplemente no entiendo por qué sigue usando AND.

Gracias.

Respuesta

16

Su problema reside en el hecho de que está creando una nueva disyunción cada vez (en un bucle). Lo que hay que hacer es:

int[] ids = {1, 2, 3}; 
ICriterion disjunction = Restrictions.Disjunction(); 
foreach (int id in ids) 
{ 
    ICriterion criterion = Restrictions.Eq("Id", id) 
    disjunction.Add(criterion); 
} 
criteria.Add(disjunction); 

La sintaxis puede ser un poco mal - Soy un tipo de hibernación en lugar de .NET :-)

Para aclarar, el código original generaría algo así como (en pseudo-código):

WHERE (OR(ID=1)) AND (OR(ID=2)) AND (OR(ID=3)) 

Dado que no hay nada de "O" para, disyunciones se omitieron en silencio.

+1

magia, que funcionaba un lujo. Tiene sentido cuando miro tu código: nunca pensé que sería "juntar" juntas OR individuales. El único cambio menor en su código es crear la disyunción como: Disyunción de unión = Restrictions.Disjunction(); (ICriterion no tiene 'agregar'). Gracias! –

5

código actualizado en base a la respuesta de ChssPly76:

using (ISession session = NHibernateHelper.OpenSession()) 
{ 
    ICriteria criteria = session.CreateCriteria<TestObject>(); 
    Junction disjunction = Restrictions.Disjunction(); 

    int[] ids = {1, 2, 3}; 
    foreach (int id in ids) 
    { 
     ICriterion criterion = Restrictions.Eq("Id", id); 
     disjunction.Add(criterion); 
    } 
    criteria.Add(disjunction); 


    IList<TestObject> items = criteria.List<TestObject>(); 
    return items; 
} 
Cuestiones relacionadas