Próbuję wykonać podstawowe „LUB” na trzech polach za pomocą zapytania kryteriów hibernacji.
Przykład
class Whatever{
string name;
string address;
string phoneNumber;
}
Chciałbym utworzyć zapytanie oparte na kryteriach, w którym mój ciąg wyszukiwania mógłby pasować do „name”, „address” lub „phoneNumber”.
(name = x AND address = y) OR (phoneNumber = z)
?Zakładając, że masz do ręki sesję hibernacji, powinno działać coś takiego:
Criteria c = session.createCriteria(Whatever.class); Disjunction or = Restrictions.disjunction(); or.add(Restrictions.eq("name",searchString)); or.add(Restrictions.eq("address",searchString)); or.add(Restrictions.eq("phoneNumber",searchString)); c.add(or);
źródło
//Expression : (c1 AND c2) OR (c3) Criteria criteria = session.createCriteria(Employee.class); Criterion c1 = Restrictions.like("name", "%e%"); Criterion c2 = Restrictions.ge("salary", 10000.00); Criterion c3 = Restrictions.like("name", "%YYY%"); Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3); criteria.add(c4);
// To samo można zrobić dla (c1 OR c2) AND c3 lub dowolnego złożonego wyrażenia.
źródło
//Expression : (c1 AND c2) OR (c3) Criteria criteria = session.createCriteria(Employee.class); Criterion c1 = Restrictions.like("name", "%e%"); Criterion c2 = Restrictions.ge("salary", 10000.00); Criterion c3 = Restrictions.like("name", "%YYY%"); Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3); criteria.add(c4); //Same thing can be done for (c1 OR c2) AND c3, or any complex expression.
źródło
Na wszelki wypadek, gdyby ktoś natknął się na to z tym samym pytaniem do NHibernate:
ICriteria c = session.CreateCriteria(typeof (Whatever)) .Add(Expression.Disjunction() .Add(Expression.Eq("name", searchString)) .Add(Expression.Eq("address", searchString)) .Add(Expression.Eq("phoneNumber", searchString)));
źródło
Warunki można zastosować za pomocą lub / i na różnych poziomach zapytania przy użyciu rozłączenia
Criteria query = getCriteria("ENTITY_NAME"); query.add(Restrictions.ne("column Name", current _value)); Disjunction disjunction = Restrictions.disjunction(); if (param_1 != null) disjunction.add(Restrictions.or(Restrictions.eq("column Name", param1))); if (param_2 != null) disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_2))); if (param_3 != null) disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_3))); if (param_4 != null && param_5 != null) disjunction.add(Restrictions.or(Restrictions.and(Restrictions.eq("column Name", param_4 ), Restrictions.eq("column Name", param_5 )))); if (disjunction.conditions() != null && disjunction.conditions().iterator().hasNext()) query.add(Restrictions.and(disjunction)); return query.list();
źródło
To właśnie zadziałało dla mnie w przypadku warunku OR, który również z warunkiem IN, a nie odpowiedzią, głosował najwięcej w tej dyskusji:
criteria.add( Restrictions.or( Restrictions.eq(ch.getPath(ch.propertyResolver().getXXXX()), "OR_STRING"), Restrictions.in(ch.getPath(ch.propertyResolver().getYYYY()), new String[]{"AA","BB","CC"}) ));
Wynikowe zapytanie:
and ( this_.XXXX=? or this_.YYYY in ( ?, ?, ? ) )
źródło
Jeśli ktoś używa CriteriaQuery zamiast Criteria, możesz umieścić wszystkie swoje wyrażenia na
Predicate
liście i umieścić OR według rozmiaru predykatów w następujący sposób:List<Predicate> predicates = new ArrayList<>(); if (...) { predicates.add(...); } criteriaQuery.where(cb.or(predicates.toArray(new Predicate[predicates.size()])));
źródło