1

下面的代码编译并正常工作,如图所示。但是,如果我尝试 yield Some("SomeConstant"),我会得到如下所示的运行时错误。

为什么会发生这种情况,如何从查询中返回表达式(例如 Some(...))?

  def cannotUnpack(db: Database) {
    db.withSession {
      val data = (for {
        rw1 <- TableOne
        rw2 <- TableTwo if rw1.cl1 === rw2.cl1 && rw1.cl2 === rw2.cl2 && rw1.cl1 === "0"
        now = new Timestamp(System.currentTimeMillis())
        six = 6
      } yield (uuid, rw1.cl3, "SomeConstant", six, now) ).list // Works
//    } yield (uuid, rw1.cl3, Some("SomeConstant"), six, now) ).list // Runtime error
    }
  }

运行时错误:不知道如何解压 (String, scala.slick.lifted.Column[Option[String]], Some[String], scala.slick.lifted.Column[Int], scala.slick.lifted.Column [java.sql.Timestamp]) 到 T 并打包到 G
rw2 <- TableTwo if rw1.cl1 === rw2.cl1 && rw1.cl2 === rw2.cl2 && rw1.cl1 === "0"
^

环境:Ubuntu上的scala 2.10,Java 7 Slick 1.0.0,SQL Server,JTDS驱动

4

2 回答 2

1

简短的回答:它有效,如果你写 Some("SomeConstant") : Option[String].

长答案:如果您在 Slick 查询中提供一个常量,则 Slick 必须将该值放入 SQL 查询中,然后从结果中读取它。这保留了可组合性,即允许您将 Slick 查询用作另一个 Slick 查询中的组件。为了将值编码到 SQL 查询中,您正在调用的方法(在理解的情况下:map 或 flatMap)需要找到 TypeMapper[T] 类型的隐式值,其中 T 是值的类型。Slick 确实定义了 TyperMapper[Option[String]] 但问题是它不适用于您的情况,因为 Some("SomeConstant") 的类型为 Some[String] 并且没有定义 TypeMapper[Some[String]]在 Slick 中(并且 TypeMapper[T] 在 T 中是不变的)。通过显式提供 :Option[String],您可以放松类型信息,因此可以找到匹配的 TypeMapper。

我们将考虑是否可以在 Slick 中添加对 Some 类型常量的支持。我添加了一张票 ( https://www.assembla.com/spaces/typesafe-slick/tickets/268 ),并将在我们的下一次团队会议中提出。

于 2013-06-14T02:45:07.797 回答
0

好吧,我不会在选择中涉及常量,但仅在管理从数据库加载的结果时才使用它们。

试试看:

 def cannotUnpack(db: Database) {
    db.withSession {
      val data = (for {
        rw1 <- TableOne
        rw2 <- TableTwo if rw1.cl1 === rw2.cl1 && rw1.cl2 === rw2.cl2 && rw1.cl1 === "0"
      } yield (uuid, rw1.cl3)
    }
  }

之后为您的需要准备好您的数据:

for (
  (uuid, rw1_cl3) <- data.list
) yield (uuid, rw1_cl3, Some("constant"), 6, new Timestamp(System.currentTimeMillis()))

在准备最终数据时,我通常使用输出案例类,例如:

case class Export(uuid: String, rw1: String, constant: Option[String], six: String, now: Timestamp)

for (
      (uuid, rw1_cl3) <- data.list
    ) yield Export(
             uuid, 
             rw1_cl3, 
             Some("constant"),  
             6, 
             new Timestamp(System.currentTimeMillis()))
于 2013-05-30T07:19:25.573 回答