2017-01-10 15 views
0

Почему это не работает, чтобы комбинировать инструкцию SELECT и DELETE в запросе Slick? как в:Как смешать выбор и удаление в транзакции Slick

val query = (for { 
    item <- SomeTable 
    _ <- OtherTable.filter(_.id === item.id).delete 
} yield()).transactionally 

"Не удается разрешить символ" транзакционно"

(без .transactionally, это Query[Nothing, Nothing, Seq], если это помогает) в то время как два действия работают отдельно:

val query = (for { 
    item <- SomeTable 
} yield()).transactionally 

,

val query = (for { 
    _ <- OtherTable.filter(_.id === 2).delete 
} yield()).transactionally 
+0

Try 'элемент <- SomeTable.result'. Я не могу получить второй пример для компиляции, «SomeTable» - это «TableQuery»? –

+0

Я пробовал. Тогда я не могу использовать 'item' для фильтрации второй таблицы, удаления или нет (я обновил первый фрагмент, чтобы показать случай). Реальный запрос сложнее. – JulienD

+0

@ insan-e 'SomeTable' является' TableQuery', да. После этого вы можете добавить «фильтр». Вы можете связать выбор операторов таким образом с помощью 'for' или удаления операторов, но не обоих. – JulienD

ответ

2

ОК, так что это классический пример смешивания DBIO с Query.

В своем первом случае:

val query = (for { 
    item <- SomeTable // this is `Query` 
    _ <- OtherTable.filter(_.id === item.id).delete // this is `DBIO` 
} yield()).transactionally 

Очевидно, что для DML вы можете использовать только действия (Query для DQL - быть просто SELECT).

Итак, первое, что нужно - измените свой код, чтобы использовать только DBIO s. Ниже приведен пример.

val query = (for { 
    item <- SomeTable.result // this is `DBIO` now 
    _ <- OtherTable.filter(_.id === item.id).delete // but this won't work !! 
} yield()).transactionally 

ОК, мы почти у цели - проблема в том, что она не компилируется. Что вам нужно сделать, это быть в курсе, что сейчас эта часть:

item <- SomeTable.result 

возвращает Seq вашего дела класса SomeTable (который среди прочего содержит ваш id).

Итак, давайте принимать во внимание:

val query = (for { 
    items <- SomeTable.result // I changed the name to `items` to reflect it's plural nature 
    _ <- OtherTable.filter(_.id.inset(items.map(_.id))).delete // I needed to change it to generate `IN` query 
} yield()).transactionally 
+0

Мне пришлось разделить вещи - сделайте выбирает в одном запросе и помещает этот запрос + удаление в транзакцию, но в конечном итоге это сработало, когда я добавил «результат». Спасибо за подробное объяснение. Нелегко проверить типы объектов в среде IDE, и я смешивал вещи с синтаксис для объединений. – JulienD