【问题标题】:slick 2.0 define generic `find by field` methodslick 2.0 定义通用的“按字段查找”方法
【发布时间】:2023-03-07 12:57:02
【问题描述】:
import scala.slick.driver.MySQLDriver.simple._

class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) {

  case class QueryExt[B](q: Query[RichTable.this.type, B])  {
    def whereEq[C](col: RichTable.this.type => Column[C], c: C) = {
      q.filter { fields =>
        col(fields) === c
      }
    }
  }

}

然后它抱怨

[error] /home/jilen/workspace/play-slick/src/main/scala/play/slick/SlickQueryExtension.scala:10: value === is not a member of slick.driver.MySQLDriver.simple.Column[C]
[error]         col(fields) === c
[error]                     ^
[error] /home/jilen/workspace/play-slick/src/main/scala/play/slick/SlickQueryExtension.scala:9: ambiguous implicit values:
[error]  both value BooleanColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Boolean]]
[error]  and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Option[Boolean]]]
[error]  match expected type scala.slick.lifted.CanBeQueryCondition[Nothing]
[error]       q.filter { fields =>
[error]                ^
[error] two errors found
[error] (compile:compile) Compilation failed
[error] Total time: 0 s, completed Mar 6, 2014 1:21:48 AM

对此有疑问,但答案不适用于 2.0

How to parametrize Scala Slick queries by WHERE clause conditions?

【问题讨论】:

    标签: scala slick slick-2.0


    【解决方案1】:

    Slick 没有关于C 的任何信息,因此它不知道它是否可以以及应该如何将其映射到数据库值以及是否可以在其上使用===。所以你得到一个类型错误。您将不得不使用 Scala 的类型系统将类型限制为 Slick 知道如何映射它的类型。您可以通过提供所谓的上下文绑定来做到这一点,在本例中为 :BaseColumnType

    def whereEq[C:BaseColumnType](col: RichTable.this.type => Column[C], c: C) = {
      q.filter { fields =>
        col(fields) === c
      }
    }
    

    BaseColumnType 由 Slick 提供,以这种方式使用它基本上告诉 Scala 编译器在范围内查找类型为 BaseColumnType[C] 的隐式值,您可以在其中 调用 whereEq。因为那时通常知道C 实际上是什么。 Slick 带有BaseColumnType[Int]BaseColumnType[String] 等,因此在调用站点上,当您的C 在该特定调用中实际上是IntString 时,Scala 编译器可以找到一个,并且通过这种方式传递信息更进一步的 Slick。

    刘虎的问题也是如此。 abstract class Crud[..., PK:BaseColumnType] 应该可以解决问题,特征不适用于上下文边界。在实现抽象 DAO 时,要准备好面对许多挑战,充分发挥 Scala 类型系统技能的优势,并学习很多关于类型推断顺序、隐式参数等方面的知识。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 2014-06-14
    • 2017-08-26
    • 2023-04-06
    • 2014-11-03
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多