【发布时间】:2017-06-13 18:12:35
【问题描述】:
我在 Play 中使用 Slick,但在尝试更新列值时遇到了一些问题,因为它没有被更新,尽管我没有收到任何错误。
我有一列告诉我是否选择了给定的行。我想要做的是获取当前选定的值(存储在 DB 列中),然后更新同一列以具有相反的值。目前(经过多次不成功的尝试)我有以下代码可以编译和运行,但在幕后没有任何反应:
val action = listItems.filter(_.uid === uid).map(_.isSelected).result.map { selected =>
val isSelected = selected.head
println(s"selected before -> $isSelected")
val q = for {li <- listItems if li.uid === uid} yield li.isSelected
q.update(!isSelected)
}
db.run(action)
我做错了什么(我是新手,所以这可能根本没有任何意义!)
【问题讨论】:
-
我写了一个语法更好看的答案。但简而言之,您的代码的问题是
result.map必须是result.flatMap。如果记录不存在,val isSelected = selected.head也可能会抛出异常。所以考虑使用selected.headOption代替我在答案中写的 -
我已经尝试了您在上面评论中提到的更改并且它有效!我只是不明白为什么
flatMap与map相比会有所不同。我也更喜欢你的回答,但我似乎无法让它发挥作用 -
map 和 flatMap 是两个非常不同的东西,而不仅仅是在您的示例中。他们的定义可以追溯到范畴论。您应该阅读该内容,但基本上以示例为例,如果您将
Int => List[String]的函数映射到List[Int],您将得到List[List[String]],但如果您将相同的函数平面映射到同一个列表,您将得到@987654331 @ 将其转换为您的示例,如果您将另一个DBIOAction[T]平映射到您的拳头DBIOAction[G]上,则结果是单个DBIOAction[T],这是您想要的,并且是两个动作的组合。
标签: database scala playframework slick