2016-02-07 1 views
1

При создании запроса таблицы я хотел бы изменить мой оператор select, сопоставляя запрос таблицы по умолчанию. Тем не менее, я не могу найти способ отображения значения столбца и по-прежнему отображаться в моем случае классСопоставление Slick запроса к проекции по умолчанию после изменения значения столбца

case class MyRecord(id: Int, name: String, value: Int) 

class MyTable(tag: Tag) extends Table[MyRecord](tag, "MYTABLE") { 
    def id = column[Int]("id") 
    def name = column[String]("name") 
    def value = column[Int]("value") 

    def * = (id, name, value) <> (MyRecord.tupled, MyRecord.unapply) 
    } 

lazy val tableQuery = TableQuery[MyTable] 

Я хотел бы, чтобы урезать значение name с this function:

def trimLeading0: (Rep[String]) => Rep[String] = SimpleExpression.unary[String, String] { 
    (str, queryBuilder) => 
     import slick.util.MacroSupport._ 
     import queryBuilder._ 
     b"TRIM(LEADING 0 FROM $str)" 
    } 

Теперь я в недоумении о том, что делать здесь:

val trimmedTableQuery: Query[MyTable, MyRecord, Seq] = tableQuery.map(s => ???) 

Я попытался отображение Rep как я хотел бы сделать с прецедентным классом:

val trimmedTableQuery = tableQuery.map(s => s.copy(name = trimLeading0(s.name))) 

Это отказывается компилировать с value copy is not a member of MyTable

Моего текущим обходным путем заключается в использовании пользовательской функции вместо MyRecord.tupled для проецирования по умолчанию:

def trimming(t: (Int, String, Int)) = MyRecord(t._1, t._2.dropWhile(_ == "0"), t._3) 
def * = (id, name, value) <> (trimming, MyRecord.unapply) 

С другой стороны, я мог бы сопоставить возвращаемый результат из DBIOAction, возвращая кортеж к классу корпуса, который намного менее изящный:

val action = tableQuery.map{ s => (s.id, trimLeading0(s.name), s.value)}.result 
val futureTuples: Future[Seq[(Int, String, Int)]] = db.run(action) 
val records = futureTuples map (s => s.map(MyRecord.tupled)) 

Но как это сделать в методе map при построении запроса? ИЛИ было бы лучше изменить описание столбца def name?

ответ

2

Вы не можете взаимодействовать с проекцией по умолчанию (т. Е. Def *) в MyTable, поскольку она должна быть симметричной. Он используется для запроса и вставки. Но вы можете создать trimmedTableQuery на основе специализации MyTable с переопределенной проекцией по умолчанию. Затем вы также можете использовать tableQuery на основе симметричной проекции по умолчанию. Вы получите сообщение об ошибке, если попытаетесь сделать вставки на основе trimmedTableQuery (но вам не нужно это делать, просто используйте tableQuery для вставок).

lazy val tableQuery = TableQuery[MyTable] 
lazy val trimmedTableQuery = new TableQuery(new MyTable(_) { 
    override def * = (id, trimLeading0(name), value) <> (MyRecord.tupled, MyRecord.unapply) 
}) 
+0

Другой отличный ответ. И я узнал здесь две вещи :) Большое спасибо, Сью С – kostja

 Смежные вопросы

  • Нет связанных вопросов^_^