Многозначный параметр Anorm 2.3: обязательный anorm.NamedParameter

Использование scala 2.11.1 в игровой среде 2.3.

Поскольку Anorm не поддерживал многозначные параметры в предыдущих версиях, я использовал Дэвида. Anorm теперь поддерживает многозначные параметры, и я начал удалять обходной путь и использовать многозначные параметры Anorm.

В примере [sic] упоминается:

// With default formatting (", " as separator)
SQL("SELECT * FROM Test WHERE cat IN ({categories})").
  on('categories -> Seq("a", "b", "c")
// -> SELECT * FROM Test WHERE cat IN ('a', 'b', 'c')

Тем не менее мой код:

val names = List("Able", "Baker", "Charlie") // Passed as a parameter to my method!
val result =
  SQL( """
    SELECT city
    FROM addresses
    WHERE name IN ({names});
  """ ).on( 'names -> names ).as( scalar[String] * )

дает мне эту ошибку:

type mismatch;
 found   : (Symbol, List[String])
 required: anorm.NamedParameter

or

type mismatch;
 found   : (Symbol, scala.collection.immutable.Seq[String])
 required: anorm.NamedParameter

в зависимости от того, пробую ли я список или последовательность (или один из предложения для сопоставления).

Я, конечно, не эксперт, и я думаю, что не хватает какого-то неявного преобразования? Невежественный, чтобы узнать, как/что/где. Советы/предложения/решения приветствуются!


person df'    schedule 05.08.2014    source источник


Ответы (1)


Глядя на документ Anorm, вы увидите, что в нем нет примера с несколькими значениями, использующего List. На самом деле это сделано специально, поскольку экземпляр NamedParameter реализован только для Seq[T].

Просто обновите свой код до val names = Seq("Able", "Baker", "Charlie"), чтобы сделать его действительным (и скомпилировать).

Я бы предложил отредактировать ваш код, используя интерполяцию Anorm:

val result = 
  SQL"SELECT city FROM addresses WHERE name IN ($names)" as scalar[String].*

// OR (if names won't change):
val result = SQL"""SELECT city FROM addresses
    WHERE name IN (${Seq("Able", "Baker", "Charlie")})""".
  as(scalar[String].*)

РЕДАКТИРОВАТЬ: Просмотреть изменения в Anorm https://github.com/playframework/playframework/pull/3257 (поддерживает список)

person cchantep    schedule 05.08.2014
comment
Боюсь, это не исправило. Смотрите мою ошибку, я уже пробовал Seq. Кое-что, что я заметил: пример Seq(A,B,C) работает, но если он не определен заранее, он не работает. Я получаю параметр в виде списка, а toSeq не работает. Кажется, что, набирая это, я мог бы найти решение: val names:Seq[String] = theList.toSeq (необходимо добавить :Seq[String]. Будет отредактировано снова, если это исправит это. - person df'; 05.08.2014
comment
Какой код вы пытаетесь использовать с Seq? Вы пробовали клеить образцы? Могу подтвердить, что все приведенные примеры работают с Anorm 2.3. Важно то, что видимый тип многозначного значения, передаваемого в качестве параметра, должен быть Seq[String]. Если вы разрешите val seq = List("a", "b"), да, seq будет экземпляром Seq, но видимый тип будет List, а неявный (typeclass) там определен не для S <: Seq[T], а строго для Seq[T]. - person cchantep; 05.08.2014
comment
Из исходного вопроса: found: (Symbol, scala.collection.immutable.Seq[String]). Это произошло потому, что я попытался преобразовать список переданных параметров в Seq. val seq = List("a", "b").toSeq. Это дало мне ошибку. Я изменил это на: val seq: Seq[String] = List("a", "b").toSeq и это сработало! Так что я думаю, что это была моя ошибка. Предполагая, что List[String].toSeq даст мне Seq[String]. (Боюсь, я мало что знаю о S‹:Set[T]. Буду искать. Это видимый тип?) Re: попробовал вставленные образцы: они работали, вот как я заметил разницу между списком .toSeq и Seq(a,b). - person df'; 05.08.2014
comment
Это не потому, что вы видите scala.collection.immutable.Seq в отладке, что видимым типом является Seq. Это List, так как List хранит строковое представление от своего родителя (.toString). Как сказано, экземпляр NamedParameter определен только для Seq[T], что означает, что ваше многозначное значение должно быть объявлено как Seq[T], а не List[T], даже если List[T] является своего рода Seq[T]: с этим неявным наследованием разрешения не следует (намеренно). Не могли бы вы принять ответ, поскольку он исправляет исходный вопрос. С наилучшими пожеланиями. - person cchantep; 05.08.2014