У меня был сценарий в Oracle, где мне нужно сопоставить часть подстроки столбца со списком значений. я использовал проекцию sqlfunction для применения подстроки к необходимому столбцу и добавил эту проекцию как часть ограничения In Clause. Ниже приведены упрощенные критерии, которые я написал для этого.
ICriteria criteriaQuery = session.CreateCriteria<Meeting>()
.Add(Restrictions.In(
Projections.SqlFunction(
"substring",
NHibernateUtil.String,
Projections.Property("Code"),
Projections.Constant(1),
Projections.Constant(3)),
new string[] { "D01", "D02" }))
.Add(Restrictions.In("TypeId", meetingTypes));
Проблема, с которой я столкнулся, заключалась в том, что сгенерированный SQL был неправильным, где число параметров, зарегистрированных для оператора, больше, чем то, которое фактически использует оператор, и некоторые параметры повторяются, даже если они не используются. Это приводит к сбою оператора с сообщением - ORA-01036: недопустимое имя / номер переменной.
Сгенерированный запрос
SELECT this_.Meeting_id as Meeting1_0_2_, .....
WHERE substr(this_.Mcs_Main, :p0, :p1) in (:p2, :p3)
and this_.Meeting_Type_Id in (:p4, :p5);
:p0 = 1, :p1 = 3, :p2 = 1, :p3 = 3, :p4 = 'D02', :p5 = 'D03', :p6 = 101, :p7 = 102
p2 и p3 генерируются снова и являются дубликатами p0, p1, из-за которых весь запрос не выполняется.
Мне удалось временно решить эту проблему, сопоставив новое свойство с формулой, но я не думаю, что это правильный подход, поскольку формула будет выполняться всегда, даже когда мне не нужна подстрока для оценки.
Любые предположения о том, хорошо ли работают проекции при использовании с сочетанием из условия In, тот же проекция работает хорошо, когда я использую Equal Restriction, а не In.