gpt4 book ai didi

scala - 将 ADT 映射到 Slick 中的多个列

转载 作者:行者123 更新时间:2023-12-05 07:55:54 25 4
gpt4 key购买 nike

我正在尝试将 ADT(case classes 继承自 sealed trait)映射为同一个表的多个列,使用 Slick,例如:

sealed trait OrValue
case class IntValue(value: Int)
case class StringValue(value: String)

case class Thing(id: Int, value: OrValue)

class Things(tag: Tag) extends Table[Thing](tag, "things") {
def id = column[Int]("id", O.PrimaryKey)
def intValue = column[Option[Int]]("intValue")
def stringValue = column[Option[String]]("stringValue")

def toThing(_id: String, _intValue: Option[Int], _stringValue: Option[String]): Thing = Thing(id, ((_intValue, _stringValue) match {
case (Some(a), None) => IntValue(a)
case (None, Some(a)) => StringValue(a)
}

def fromThing(t: Thing): (String, Option[Int], Option[String]) = ??? // elided

def * = (id, intValue, stringValue) <> ((toThing _).tupled, fromThing)
}

这不是编译:

[error]  found   : [U]slick.lifted.MappedProjection[Thing,U]
[error] required: slick.lifted.ProvenShape[Thing]
[error] ) <> ((toThing _).tupled, fromThing _)

我是不是用错了方法?表示 ADT 的惯用方式是什么?

最佳答案

问题出在方法 toThingfromThing 的签名中。

它应该是这样的:

sealed trait OrValue
case class IntValue(value: Int)
case class StringValue(value: String)

case class Thing(id: Int, value: OrValue)

class Things(tag: Tag) extends Table[Thing](tag, "things") {
def id = column[Int]("id", O.PrimaryKey)
def intValue = column[Option[Int]]("intValue")
def stringValue = column[Option[String]]("stringValue")

def toThing(source: (Int, Option[Int], Option[String])): Thing = source match {
case (id, intValue, stringValue) => ??? //TODO implement
}
def fromThing(t: Thing): Option[(Int, Option[Int], Option[String])] = ??? //TODO implement

def * = (id, intValue, stringValue) <> (toThing _, fromThing _)
}

关于scala - 将 ADT 映射到 Slick 中的多个列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29258822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com