【发布时间】:2016-05-17 16:42:27
【问题描述】:
下面的代码有效,但我不禁认为我对 asInstanceOf[B] 演员表做了一些不恰当的事情。
本质上,在传递某种类型的TableQuery 之后,我希望mapper 变成一个动作,根据我传递给它的函数将结果和map 它变成一个DAO 列表。
我坚持的是函数的类型,或者可能是如何公开 TableQuery 类型的内部类型。我想做类似[B <: TableElementType] f: B => A 之类的事情,而不是对 B 进行可能残酷的演员表。
我想我知道我将在下面的示例中得到类似AgencyRow 的东西来映射到 AgencyDAO,我如何在方法的类型签名中捕获它?
映射器
def mapper[A <: BaseDAO, B <: DatabaseAccessObject, T <: TableQuery[E], E <: AbstractTable[_]](query: T, f: B => A) : Seq[A] = {
val result = exec(query.result)
result.map(o => f(o.asInstanceOf[B]))
}
def exec[T](action: DBIO[T]): T = Await.result(db.run(action), 4 seconds)
使用映射器(测试代码)
val list = mapper[AgencyDAO, AgencyRow, TableQuery[Agency], Agency](agencies, AgencyDAODomainObject.convertFromRow)
list.length should equal(75)
Slick 架构
case class AgencyRow(id: Int, name: Option[String] = None) extends DatabaseAccessObject
class Agency(_tableTag: Tag) extends Table[AgencyRow](_tableTag, "agency") {
def * = (id, name) <>(AgencyRow.tupled, AgencyRow.unapply)
def ? = (Rep.Some(id), name).shaped.<>({ r => import r._; _1.map(_ => AgencyRow.tupled((_1.get, _2))) }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))
val id: Rep[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
val name: Rep[Option[String]] = column[Option[String]]("name", O.Length(200, varying = true), O.Default(None))
}
lazy val Agency = new TableQuery(tag => new Agency(tag))enter code here
DAO 映射器
package object Implicits {
implicit class DomainObjectOps[A <: BaseDAO](a: A)(implicit ev: DomainObject[A]) {
def name = ev.name(a)
def id = ev.id(a)
}
}
trait BaseDAO
trait DomainObject[A <: BaseDAO] {
def id(a: A): Int
def name(a: A): String
}
case class AgencyDAO(val id: Int, val name: String) extends BaseDAO
object AgencyDAO {
implicit object AgencyDAODomainObject extends DomainObject[AgencyDAO] {
def convertToRow(o: AgencyDAO) = AgencyRow(o.id, Some(o.name))
def convertFromRow(o: AgencyRow) = AgencyDAO(o.id, o.name.getOrElse(""))
override def id(a: AgencyDAO) = a.id
override def name(a: AgencyDAO) = a.name
}
}
【问题讨论】:
-
您在
mapped的第一行中使用的TableQuery.result的签名是什么?我似乎找不到its definition。 -
@dcastro 所以,我的理解是它是 DBIOAction 的一个实例,但它是特定于数据库驱动程序的(通过导入适当的 api 公开)所以你最终会得到类似 PostgresDriver.StreamingDriverAction 的东西