【问题标题】:Slick mapped tables using traits throws exception使用特征的光滑映射表引发异常
【发布时间】:2016-05-07 06:25:20
【问题描述】:

我一直在尝试使用 slick 3.1.0 中的特征定义映射表。由于官方文档中没有提到任何内容,我什至不确定这是否可能。这是我目前所拥有的:

表定义:

class PersonTable(tag: Tag) extends Table[PersonModel](tag, "person") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def firstName = column[String]("first_name", O.Length(PersonDb.FirstNameColumnLength))
  def lastName = column[String]("last_name", O.Length(PersonDb.LastNameColumnLength))

  def * = (id.?, firstName, lastName) <> (PersonModelImpl.tupled, PersonModelImpl.unapply _)
}

人物模型:

trait PersonModel {
  def id: Option[Int]
  def firstName: String
  def lastName: String
}

PersonModelImpl:

case class PersonModelImpl(
    override val id: Option[Int],
    override val firstName: String,
    override val lastName: String)
  extends PersonModel

编译上面的代码会报错:

Compilation error[type mismatch;
  found   : slick.lifted.MappedProjection[models.PersonModelImpl,(Option[Int], String, String]
  required: slick.lifted.ProvenShape[models.PersonModel]]

但是,在表定义中将 ...extends Table[PersonModel]... 更改为 ...extends Table[PersonModelImpl]... 可以正常工作。

所以基本上我的问题是:

  1. 是否可以在映射表中使用特征作为TableElementType
  2. 如果是,我做错了什么?

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    答案:

    1. 可以,但需要正确的投影函数 (*)。
    2. * 的类型有误。为了使隐式解析到正确的MappedProjection,类型必须完全匹配。

    您应该能够通过以下方式解决这两个问题:

    def * = {
      val applyAsPersonModel: (Option[Int], String, String) => PersonModel =
        (PersonModelImpl.apply _)
      val unapplyAsPersonModel: PersonModel => Option[(Option[Int], String, String)] =
        { 
          // TODO: Handle any other subclasses of PersonModel you expect.
          case personImpl: PersonModelImpl => PersonModelImpl.unapply(personImpl)
        }
      (id.?, firstName, lastName) <> (applyAsPersonModel.tupled, unapplyAsPersonModel)
    }
    

    注意 TODO。如果您尝试插入任何非PersonModelImpl 实例,除非您向该部分函数添加额外的case 语句,否则您将遇到异常。或者,您可以创建一个新的PersonModelImpl 实例以传递给unapply

    val unapplyAsPersonModel: PersonModel => Option[(Option[Int], String, String)] =
      { person: PersonModel =>             
        PersonModelImpl.unapply(
          PersonModelImpl(person.id, person.firstName, person.lastName)
        )
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 2014-03-14
      • 1970-01-01
      • 2018-06-15
      相关资源
      最近更新 更多