我试图模板化一个TableQuery成员,但路径依赖类型让我搞砸了。我有一个典型的代码生成表,如下所示:
trait TablesContainer {
case class MembersRow(firstName:String, lastName:String)
class Members(_tableTag: Tag) extends Table[MembersRow](_tableTag, Some("dbo"), "MEMBERS") {
def * = (firstName, lastName) <> (MembersRow.tupled, MembersRow.unapply)
val firstName: Rep[String] = column[String]("FIRM_NAME")
val lastName: Rep[String] = column[String]("LAST_NAME")
}
}
然后我尝试创建一个将采用TableQuery(在典型的multi-db模式中)的类,如下所示:
class TemplateHolder(profile: RelationalProfile) {
import profile.api._
class InsertionTemplate[T <: Table[E], E](tableQuery: TableQuery[T]) {
def apply(insertRow:E) = {
tableQuery += insertRow
}
}
}
然后我想这样使用它:
def template = new InsertionTemplate(TableQuery[TablesContainer.Members])
template.apply(MembersRow("Joe", "Bloggs"))
只有我收到错误:
Error:(134, 28) inferred type arguments [com.test.TablesContainer.Members,Nothing] do not conform to class InsertionTemplate's type parameter bounds [T <: RelationalProfileConstants.this.profile.api.Table[E],E]
def template = new InsertionTemplate(TableQuery[TablesContainer.Members])
然后这一个:
Error:(134, 60) type mismatch;
found : slick.lifted.TableQuery[com.test.TablesContainer.Members]
required: RelationalProfileConstants.this.profile.api.TableQuery[T]
(which expands to) slick.lifted.TableQuery[T]
def template = new InsertionTemplate(TableQuery[TablesContainer.Members])
我做错了什么?
答案 0 :(得分:3)
以下代码编译没有问题。 InsertionTemplate
方法无法推断E的类型,因此明确提供类型参数解决了问题。导入的范围也可能存在潜在问题。确保您拥有导入语句import driver.api._
,如下所示。
trait Container1 {
self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
trait TablesContainer {
case class MembersRow(firstName:String, lastName:String)
class Members(_tableTag: Tag) extends Table[MembersRow](_tableTag, Some("dbo"), "MEMBERS") {
def * = (firstName, lastName) <> (MembersRow.tupled, MembersRow.unapply)
val firstName: Rep[String] = column[String]("FIRM_NAME")
val lastName: Rep[String] = column[String]("LAST_NAME")
}
}
}
trait Container2 {
self: HasDatabaseConfigProvider[JdbcProfile] with Container1 =>
import driver.api._
class InsertionTemplate[T <: Table[E], E](tableQuery: TableQuery[T]) {
def apply(insertRow:E) = {
tableQuery += insertRow
}
}
class Run extends TablesContainer {
// specify explicit type parameters.
def template = new InsertionTemplate[Members,MembersRow](TableQuery[Members])
template.apply(MembersRow("Joe", "Bloggs"))
}
}