我正在尝试为Slick 2.0编写一个通用的CRUD特性.该特征应该a)提供读取/更新/删除实体的通用方法以及b)数据库中的摘要.在
this slick example(数据库抽象)和
this article(CRUD特征)之后,我想出了以下(缩短的)代码片段:
trait Profile {
val profile: JdbcProfile
}
trait Crud[T <: AbstractTable[A], A] { this: Profile =>
import profile.simple._
val qry: TableQuery[T]
def countAll()(implicit session: Session): Int = {
qry.length.run
}
def getAll()(implicit session: Session): List[A] = {
qry.list // <-- type mismatch; found: List[T#TableElementType] required: List[A]
}
}
由于类型不匹配,代码无效.第二个函数的返回类型似乎是List [T#TableElementType]类型,但需要是List [A].关于如何解决问题的任何想法.还欢迎对通用Slick 2.0操作的进一步阅读的其他参考.
最佳答案 类型TableElementType在类AbstractTable [A]中是抽象的. Scala不知道A和TableElementType之间的任何关系.另一方面,类表定义了最终类型TableElementType = A,它告诉Scala关于这种关系(显然Scala足够聪明,可以使用最终注释来知道关系甚至适用于子类型T<:Table [A] eventHough表[A]在A)中不是共变体. 因此,您需要使用T<:Table [A]而不是T< ;: AbstractTable [A].而且因为Table位于Slick驱动蛋糕内(如蛋糕模式),所以你需要将Crud移动到你的蛋糕中.蛋糕是病毒的.
trait Profile {
val profile: JdbcProfile
}
trait CrudComponent{ this: Profile =>
import profile.simple._
trait Crud[T <: Table[A], A] {
val qry: TableQuery[T]
def countAll()(implicit session: Session): Int = {
qry.length.run
}
def getAll()(implicit session: Session): List[A] = {
qry.list // <-- works as intended
}
}
}