我试图在光滑的3.1.0中使用traits来定义映射表。由于官方文档中没有提到任何内容,我甚至不确定这是否可行。以下是我到目前为止的情况:
表格定义:
class PersonTable(tag: Tag) extends Table[PersonModel](tag, "person") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def firstName = column[String]("first_name", O.Length(PersonDb.FirstNameColumnLength))
def lastName = column[String]("last_name", O.Length(PersonDb.LastNameColumnLength))
def * = (id.?, firstName, lastName) <> (PersonModelImpl.tupled, PersonModelImpl.unapply _)
}
PersonModel:
trait PersonModel {
def id: Option[Int]
def firstName: String
def lastName: String
}
PersonModelImpl:
case class PersonModelImpl(
override val id: Option[Int],
override val firstName: String,
override val lastName: String)
extends PersonModel
编译上面的代码会导致错误:
Compilation error[type mismatch;
found : slick.lifted.MappedProjection[models.PersonModelImpl,(Option[Int], String, String]
required: slick.lifted.ProvenShape[models.PersonModel]]
但是,在表格定义中将...extends Table[PersonModel]...
更改为...extends Table[PersonModelImpl]...
可以完美无缺地工作。
基本上我的问题是:
TableElementType
?答案 0 :(得分:1)
数目:
*
)。*
上的类型错误。为了使隐式解析到正确的MappedProjection
,类型必须完全匹配。您应该可以通过执行以下操作来解决这两个问题:
def * = {
val applyAsPersonModel: (Option[Int], String, String) => PersonModel =
(PersonModelImpl.apply _)
val unapplyAsPersonModel: PersonModel => Option[(Option[Int], String, String)] =
{
// TODO: Handle any other subclasses of PersonModel you expect.
case personImpl: PersonModelImpl => PersonModelImpl.unapply(personImpl)
}
(id.?, firstName, lastName) <> (applyAsPersonModel.tupled, unapplyAsPersonModel)
}
请注意TODO。如果您尝试插入任何非PersonModelImpl
实例,除非向该部分函数添加其他case
语句,否则您将收到异常。或者,您可以创建一个新的PersonModelImpl
实例以传递给unapply
:
val unapplyAsPersonModel: PersonModel => Option[(Option[Int], String, String)] =
{ person: PersonModel =>
PersonModelImpl.unapply(
PersonModelImpl(person.id, person.firstName, person.lastName)
)
}