如何通过scala-slick在同一行中将一列的值设置为另一列

How to set the value from one column to another in the same row by scala-slick

example code
就我而言:

import slick.jdbc.MySQLProfile.api._
import scala.concurrent.Await
import scala.concurrent.duration.Duration

case class User(id: Option[Int], vid: Int, first: String, last: String)

  class Users(tag: Tag) extends Table[User](tag, "users") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def vid = column[Int]("vid")
    def first = column[String]("first")
    def last = column[String]("last")
    def * = (id.?, vid, first, last) <> (User.tupled, User.unapply)
  }
  val users = TableQuery[Users]

  def usersForInsert = users.map(u => (u.vid, u.first, u.last).shaped <>
    ({t => User(None, t._1, t._2, t._3)}, {(u: User) => Some((u.vid, u.first, u.last))}))

//#insert vid value
   val userWithId =
     (users returning users.map(_.id)
        into ((user,id) => user.copy(id=Some(id)))

     //Here, I wonder how to replace the value of vid by id
     ) += User(None, 4, "Stefan", "Zeiger")
//#insert

    val userWithIdRes = Await.result(db.run(users.schema.create >> userWithId), Duration.Inf)
    println(userWithIdRes)

我尝试了一些方法,但编译时总是出错,运行。
感谢您阅读 scala-slick

初级问题

正如您定义 User.idAutoInc 一样,您不能在插入操作上有值。它将由数据库系统生成。所以你可以先插入并获取 id 然后更新你想要的列。这可以像这样完成:

val newUserId: Future[Int] =
    for {
      userId <- db.run(
        (users returning users.map(_.id)) += User(None, 0, "Stefan", "Zeiger")
      )
      _ <- db.run(users.filter(_.id === userId).map(_.vid).update(userId))
    } yield userId

但是,有一个额外的数据库调用。这可能会导致将来可能出现快速写入的性能问题。如果只是出于学习目的,是的,它是可行的,但在实际代码库中,最好以不同的方式进行设计。例如 vid 总是与 id 具有相同的值,因此您可以在应用程序级别使用 vid,但不一定在数据库中使用。