6

类和表定义如下所示:

case class Group(
  id: Long = -1,
  id_parent: Long = -1,
  label: String = "",
  description: String = "")

  object Groups extends Table[Group]("GROUPS") {
    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def id_parent = column[Long]("ID_PARENT")
    def label = column[String]("LABEL")
    def description = column[String]("DESC")
    def * = id ~ id_parent ~ label ~ design <> (Group, Group.unapply _)
    def autoInc = id_parent ~ label ~ design returning id into {
      case ((_, _, _), id) => id
    }
  }

要更新记录,我可以这样做:

  def updateGroup(id: Long) = Groups.where(_.id === id)

  def updateGroup(g: Group)(implicit session: Session) = updateGroup(g.id).update(g)

但我无法使用 for 表达式获得更新:

  val findGById = for {
    id <- Parameters[Long]
    g <- Groups; if g.id === id
  } yield g

  def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g)
  ----------------------------------------------------------------------------^
Error: value update is not a member of scala.slick.jdbc.MutatingUnitInvoker[com.exp.Group]

我显然在文档中遗漏了一些东西。

4

2 回答 2

7

update方法由 type 提供UpdateInvoker。如果它们在范围内,则可以Query通过方法productQueryToUpdateInvoker和/或tableQueryToUpdateInvoker(在 中找到)从 a 隐式创建该类型的实例。BasicProfile

现在您的findById方法的类型不是 aQuery而是 a BasicQueryTemplate[Long, Group]。查看文档,我找不到从 a BasicQueryTemplate(它是 的子类型StatementInvoker)到 a 的方法UpdateInvoker,既不是隐含的也不是显式的。想一想,这对我来说有点道理,因为我理解查询模板(调用程序)是Query在参数化之前很早就从抽象语法树()“编译”为准备好的语句的东西,而更新调用程序只能从抽象语法树(即Query对象)构建,因为它需要分析查询并提取其参数/列。至少目前看来是这样的。

考虑到这一点,一个可能的解决方案展开:

def findGById(id: Long) = for {
  g <- Groups; if g.id === id
} yield g

def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g)

WherefindById(id: Long)具有Query[Groups, Group]转换productQueryToUpdateInvokerUpdateInvoker[Group]最终update可以调用方法的类型的类型。

希望这有帮助。

于 2013-02-26T21:58:17.250 回答
4

参考http://madnessoftechnology.blogspot.ru/2013/01/database-record-updates-with-slick-in.html

我今天坚持更新,这篇博文对我帮助很大。另请参阅帖子下的第一条评论。

于 2013-08-05T18:19:24.787 回答