【发布时间】:2017-02-08 10:08:12
【问题描述】:
我正在使用 Slick 3.1.1,问题是在某些情况下,我想省略一些相当重的列,并且仍然将该列子集具体化为案例类。
考虑下面的表定义:
class AuditResultTable(tag: Tag) extends Table[AuditResult](tag, AuditResultTableName) {
def auditResultId: Rep[Long] = column[Long]("AuditResultId", O.PrimaryKey, O.AutoInc)
def processorId: Rep[Long] = column[Long]("ProcessorId")
def dispatchedTimestamp: Rep[Timestamp] = column[Timestamp]("DispatchedTimestamp", O.SqlType("timestamp(2)"))
def SystemAOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemAOutput", O.SqlType("LONGBLOB"))
def SystemBOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemBOutput", O.SqlType("LONGBLOB"))
def isSuccessful: Rep[Boolean] = column[Boolean]("IsSuccessful")
def * : ProvenShape[AuditResult] = (processorId, dispatchedTimestamp, systemAOutput, systemBOutput, isSuccessful, auditResultId) <>
(AuditResult.tupled, AuditResult.unapply)
}
val auditResults = TableQuery[AuditResultTable]
对应的案例类:
case class AuditResult (
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
SystemAOutput: Array[Byte],
SystemBOutput: Array[Byte],
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)
最后是数据访问查询:
def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResult, Seq] = {
auditResults.filterNot(r => r.isSuccessful)
}
我已经考虑并研究了in this (outdated) answer 和其他人提出的选项:
- 具有与默认投影不同的投影,默认投影映射到“
AuditResult的轻型版本,例如AuditResultLight,省略了这些列 - 尽管我尽了最大努力,但我无法完成这项工作 - 我感觉像这样 应该是正确的方法——一旦我有了一个“工作”的投影,我仍然得到一个 Slick 错误“没有找到匹配的形状。 Slick 不知道如何映射给定的类型” - 使用抽象
AuditResultTableBase类和派生自它的两个类构建一个类层次结构 - 一个添加“重”列,一个不添加它们,两者都有各自的默认投影和案例类。这很好用,但这种方法似乎是错误的,并且需要对如此简单的事情进行相对较大的代码更改。 - 物化元组而不是案例类 - 这当然可以,但我希望我的数据访问层是强类型的。
对于这个问题,Slick 3.1 的惯用/最佳实践是什么?我可以为此使用自定义投影吗?如果可以,这个特定示例/查询会是什么样子?SystemAOutput 和SystemBOutput 是我想省略的重列?
【问题讨论】: