scala – 使用Slick 2.0的通用CRUD操作

我正在尝试为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&lt ;: 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
    }
  }
}
点赞