下面的代码编译并正常工作,如图所示。 但是,如果我尝试产生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&lt; - TableTwo如果rw1.cl1 === rw2.cl1&amp;&amp; rw1.cl2 === rw2.cl2&amp;&amp; rw1.cl1 ===“0”
^
环境: scala 2.10在Ubuntu上,Java 7 Slick 1.0.0,SQL Server,JTDS驱动程序
答案 0 :(得分: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),并将在下次团队会议中提出。
答案 1 :(得分:0)
好吧,我不会在常规中涉及常量,但只在管理从DB加载的结果时才使用它们。
尝试如下:
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()))