我试图将行与同一个表中的其他行连接起来,即自连接。
这是我的模型(有点简化,我的版本还有12个cols):
case class Log(id: Option[Long], createdAt: Date, state: Int, duplicateOf: Option[Long] = None)
class LogsTable(tag: Tag) extends Table[Log](tag, "log") {
def id = column[Option[Long]]("id", O.PrimaryKey, O.AutoInc)
def createdAt = column[Date]("created_at", O.NotNull)
def state = column[Int]("state", O.NotNull)
def duplicateOf = column[Option[Long]]("duplicate_of", O.Nullable)
def * = (id, createdAt, state, duplicateOf) <> (Log.tupled, Log.unapply _)
}
这是我的疑问:
val q = for {
(logs, duplicates) <- Tables.logs.filter(_.duplicateOf.isEmpty) leftJoin Tables.logs on (_.id === _.duplicateOf )
} yield (logs, duplicates)
失败的
[SlickException: Read NULL value (null) for ResultSet column Path s2._19]
由于列被定义为Option [Long]和Nullable,我不确定它为什么会失败。有什么建议吗?
答案 0 :(得分:0)
现在Slick对左和右有一些限制,对可为空的行有完整的外连接。 但是你可以处理可以为空的行(可能这不是最好的方法)
def getLogs()(implicit session: Session): List[(Log, Option[Log])] = {
(for {
(logs, duplicates) <- Tables.logs.filter(_.duplicateOf.isEmpty) leftJoin Tables.logs on (_.id === _.duplicateOf)
} yield (logs, (duplicates.id, duplicates.createdAt.?, duplicates.state.?, duplicates.duplicateOf))).list
.map {
case (log1, log2) =>
(log1, if (log2._1.isDefined) None else Some(Log(log2._1, log2._2.get, log2._3.get, log2._4)))
}
}
答案 1 :(得分:-2)
我认为您希望使用filterNot
代替filter
。