Как указать столбец SortBy запроса SLICK из параметра runtime?

У меня есть следующий запрос SLICK для получения постраничных результатов для таблицы данных с полем имени, соответствующим некоторым критериям значения и отсортированным по столбцу имен

val q = ThirdParties.where(_.name like criteria).sortBy(_.name.asc.nullsLast).drop(offset).take(pageSize)
val thirdParties = (for(s <-q) yield(s)).list map { case t: ThirdParty => t }

Это работает нормально для меня, но теперь мне нужно передать параметр runtime в метод sortBy, который идентифицирует столбец, на котором будет выполняться сортировка.
Мой метод, который вызывает запрос, будет иметь int, который представляет индекс столбца в таблице данных.

Как я могу получить от индекса int-столбца нужный тип, требуемый методом sortBy?

Ответ 1

Вы потеряете некоторую безопасность типов, сделав это, но, возможно, такой подход повредит:

Это пример кофе из документации Slick. Предположим, вы хотите, чтобы подмножество ваших столбцов адресовано индексом. В нашем примере давайте по какой-то причине мы сидели, 2 цена Int, а также продажи который мы адресуем как столбец 0, 1 или 2. , Если вы можете мириться с незначительным нарушением DRY, например:

object Coffees extends Table[(String, Int, Double, Double, Int, Int)]("COFFEES") {
  def name = column[String]("COF_NAME", O.PrimaryKey)
  def supID = column[Int]("SUP_ID")
  def price1 = column[Double]("PRICE1")
  def price2 = column[Double]("PRICE2")
  def sales = column[Int]("SALES")
  def total = column[Int]("TOTAL")
  def * = name ~ supID ~ price1 ~ price2 ~ sales ~ total
  def nth = Vector(price1, price2, sales) // Your index-addressable columns 
}

Здесь Coffees.nth - вектор столбцов, как Int, так и Double.

scala> Coffees.nth
scala.collection.immutable.Vector[scala.slick.lifted.Column[_ >: Int with Double <: AnyVal]] = Vector(COFFEES.PRICE1, COFFEES.PRICE2, COFFEES.SALES)

Конечно, выбор столбца для сортировки во время выполнения подразумевает, что вам нужно иметь дело с фиктивные индексы столбцов - если у вас есть только столбцы k, и вы запрашиваете k+1 th column вам нужно либо выбросить исключение, либо тихо выбрать столбец по умолчанию. Который следствием желания перевести динамический вклад в то, что обычно статично (и типа).

Если вы используете исключение для индекса фиктивного столбца, то (вернемся к вашему примеру)

 def q(colIndx: Int) = ThirdParties.where(_.name like criteria).
       sortBy(_.nth(colIndx).asc.nullsLast).
       drop(offset).take(pageSize)

Затем для вызова запроса

 val colIndx: Int = // gotten at runtime
 val thirdParties = (for(s <-q(colIndx)) yield(s)).list map { case t: ThirdParty => t }