【问题标题】:KeyedEntity in Squeryl 0.9.6Squeryl 0.9.6 中的 KeyedEntity
【发布时间】:2012-12-19 06:49:35
【问题描述】:

Squeryl 0.9.6 版引入了一种新方法来声明具有关联主键through the use of the KeyedEntityDef typeclass 的类。还是老办法声明

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] in 范围,或者它扩展了特征 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)
  }
}

无助于隐式解析,trait 无法编译。

有没有人知道为什么编译器没有提供 lookup method 中的隐含内容?

【问题讨论】:

    标签: scala implicit-conversion squeryl


    【解决方案1】:

    查找方法的签名已更改,因此它接受 KeyedEntityDef 作为隐式参数。为了向后兼容,有一个 KeyedEntityDef 可用于 KeyedEntity 类型。它可以在 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 一起使用。

    【讨论】:

    • 谢谢。我尝试了您提到的两种解决方案。至于第一个,PrimitiveTypeMode._ 已经在那里,但没有帮助。我认为这与隐式KeyedEntityDef[Long, _] 必须由隐式ev: A &lt;:&lt; KeyedEntity[Long] 的隐式转换产生的事实有关,我不确定Scala 是否两次应用隐式解析。我也尝试了第二种方法,但每当我使用get 时,我都会收到错误...
    • both method stringCanBuildFrom in object Predef of type =&gt; scala.collection.generic.CanBuildFrom[String,Char,String] and method kedForKeyedEntities in trait QueryDsl of type [A, K](implicit ev: &lt;:&lt;[A,org.squeryl.KeyedEntity[K]], implicit m: Manifest[A])org.squeryl.KeyedEntityDef[A,K] match expected type &lt;error&gt; forSome { type _$1 }
    • 我的错,您的第二个解决方案工作正常。我没有在特征Retrievable 的范围内导入KeyedEntityDef,但是错误在一长串错误消息中丢失了。
    • 啊,对于第一个,问题不在于隐式需要解决两次....而是QueryDsl中的kedForKeyedEntities方法需要Manifest。在编译时无法为 A 生成 Manifest,因此编译失败。无论如何,第二种解决方案是更好的解决方案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多