【问题标题】:Scala Slick value foreach is not a member ofScala Slick 值 foreach 不是
【发布时间】:2020-08-21 04:58:44
【问题描述】:

这是一个用于连接 MariaDB 的 Scala Play 项目。

cat build.sbt
...
jdbc,
"org.mariadb.jdbc" % "mariadb-java-client" % "2.6.2",
"com.typesafe.slick" %% "slick" % "3.3.2",
...
class Users(tag: Tag) extends Table[(...)](tag, "USERS") {...}

val users = TableQuery[Users]

for (u <- users) {...}

错误:

value foreach is not a member of slick.lifted.TableQuery[controller.Users]

for (u <- users) {
          ^

我尝试在 for 循环中将 .result 添加到 users,但我得到了

value foreach is not a member of slick.jdbc.MySQLProfile.StreamingProfileAction[Seq[controller.Users#TableElementType],controller.Users#TableElementType,slick.dbio.Effect.Read]

for (u <- users.result) {
                ^

我的代码中没有db.run。

【问题讨论】:

  • 没有yield 子句的for 理解编译信息.foreach() 调用您的集合。如果您的集合不支持 foreach() 方法,那么您必须使用不同的方法来迭代集合。

标签: scala for-loop foreach slick


【解决方案1】:

您似乎想要遍历数据库中的用户。

这里需要几个概念:

  • 表达式users 是一种查询。像map 和filter 这样的方法是一种产生替代查询的方法。使用foreach 迭代查询 并没有什么意义。

  • 有了users.results,你就有了一个动作(一种DBIOAction)。这是您可以发送到数据库的内容,带有db.run。同样,map 或 flatMap 之类的方法是一种转换和组合动作的方法,但使用 foreach 迭代 一个动作 并没有真正意义。

那该怎么办? users.result 的签名类似于 DBIO[Seq[User]]。如果您想对每个用户做某事,也许将它们打印出来,您可以构建一个动作来做到这一点。一种方法是将map 操作的结果(用户列表)传递给其他东西。也许:

val doSomethingWithEachUser: DBIO[Unit] = 
  users.result.map { seqUsers => 
    seqUsers.foreach(println)
  }

这里我们使用map 将DBIO[Seq[User]] 的结果类型更改为DBIO[Unit]。

然后您可以使用db.run 将doSomethingWithEachUser 发送到数据库(可以这么说)。当您这样做时,您的操作就会运行,并且当值可用时,println 将会发生。

要切换回 for 理解,您可以看到我们需要构造一个新动作:

val doSomethingWithEachUser: DBIO[Unit] =
  for {
    allUsers <- messages.result
  } yield allUsers.foreach(println)

...例如。

下一层将在Future 中,这是db.run 的结果。您还可以在 future 上使用 map(或类似名称)来处理数据。 Slick 几乎全是关于查询、操作和(最终)期货的这些类型的构建块,并使用 map 和 flatMap 等组合符来操作它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    相关资源
    最近更新 更多