4

Slick 2.0 の一般的な CRUD トレイトを作成しようとしています。トレイトは、a )エンティティを読み取り/更新/削除するための一般的なメソッドを提供し、b)データベースから抽象化する必要があります。この洗練された例(データベースの抽象化) とこの記事(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]
  }
}

タイプが一致しないため、コードは無効です。2 番目の関数の戻り値の型は型のようですが、List[T#TableElementType]List[A] である必要があります。問題を解決する方法についてのアイデア。一般的な Slick 2.0 操作に関するさらなる資料への追加の参照も歓迎します。

4

1 に答える 1

2

type TableElementTypeの内部は抽象的ですclass AbstractTable[A]AScala はとの間の関係を知りませんTableElementTypeclass Table一方、 defineはfinal type TableElementType = A、この関係について Scala に伝えます (明らかに、Scala はアノテーションを使用して、が共変でなくfinalてもサブタイプにも関係が成り立つことを知るのに十分スマートです)。T <: Table[A]Table[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
    }
  }
}
于 2014-03-11T23:49:10.680 に答える