0

Squeryl 0.9.6 版引入了一种新方法,通过使用KeyedEntityDeftypeclass来声明具有关联主键的类。仍然是旧的声明方式

import org.squeryl.KeyedEntity

case class Foo(id: Long, myField: String) extends KeyedEntity[Long]

支持。

我正在尝试将使用 Squeryl 0.9.5 的现有应用程序迁移到新版本,以使用自定义原始类型,但我正面临编译问题。这是一个不再编译的特征示例

trait Retrievable[A <: KeyedEntity[Long]] {
  def table: Table[A]

  def get(id: Long): Option[A] = inTransaction {
    table.lookup(id)
  }
}

它本来是这样使用的:

case class Foo(id: Long, myField: String) extends KeyedEntity[Long]

object Foo extends Retrievable[Foo] {
  def table = DB.something
}

...

val foo = Foo.get(235)

现在,当我尝试编译时,我收到了消息

该方法需要在范围内隐含 org.squeryl.KeyedEntityDef[A, Long],或者它扩展了特征 KeyedEntity[{K}]

虽然A确实延长了KeyedEntity[Long]。甚至在范围内添加一个隐式,比如

trait Retrievable[A <: KeyedEntity[Long]] {
  def table: Table[A]
  implicit val ev: <:<[A, KeyedEntity[Long]]

  def get(id: Long): Option[A] = inTransaction {
    table.lookup(id)
  }
}

对隐式解析没有帮助,并且特征无法编译。

有谁知道为什么编译器没有提供查找方法中的隐式?

4

1 回答 1

4

查找方法的签名已更改,因此它接受 KeyedEntityDef 作为隐式参数。为了向后兼容,有一个可用于 KeyedEntity 类型的 KeyedEntityDef。它可以在 QueryDsl 中找到(参见 kedForKeyedEntities 隐式方法),并且旨在作为您正在使用的“TypeMode”(即 PrimitiveTypeMode)的一部分导入范围。快速的答案是您有两个选择:

  • 确保 PrimitiveTypeMode._ 在定义 Retrievable 特征的范围内
  • 为了使其更灵活,让您的 get 方法接受与查找相同的隐式参数def get(id: Long)(implicit ked: KeyedEntityDef[T,K], dsl: QueryDsl): Option[A],然后将它们传递给table.lookup(id)(ked, dsl). 这将推迟他们的解决方案,直到您的 get 方法被调用并允许它与您定义的任何自定义 TypeMode 一起使用。
于 2012-12-18T22:49:35.187 回答