我正在使用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不知道如何映射给定的类型“AuditResultTableBase
类和从中派生的两个类构建一个类层次结构 - 一个添加“重”列,另一个不添加它们,两者都有各自的默认投影和案例类。这很好用,但这种方法看起来很错误,并且需要进行相对较大的代码更改才能实现这么简单的事情。 Slick 3.1解决此问题的惯用/最佳做法是什么?我是否可以为此使用自定义投影?如果是这样,对于SystemAOutput
和SystemBOutput
这个我要忽略的重列的特定示例/查询,它会是什么样子?
答案 0 :(得分:5)
我有类似的问题!你必须定义形状!在documentation的帮助下,我成功地使用&#34; light&#34;案例类工作。
首先,定义更简单的类:
case class AuditResultLight(
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)
然后,您需要创建案例类的提升版本:
case class AuditResultLightLifted(
ProcessorId: Rep[Long],
DispatchedTimestamp: Rep[Timestamp],
IsSuccessful: Rep[Boolean],
AuditResultId: Rep[Long]
)
此外,您需要一个隐式对象(形状)来告诉光滑如何将一个映射到另一个:
implicit object AuditResultLightShape
extends CaseClassShape(AuditResultLightLifted.tupled, AuditResultLight.tupled)
现在,您可以定义一个返回AuditResultLight的查询(不完全是一个投影,但据我所知,它的工作方式类似):
val auditResultsLight = auditResults.map(r => AuditResultLightLifted(r.ProcessorId, r.DispatchedTimestamp, r.IsSuccessful, r.AuditResultId))
然后,您可以定义以灯光形式返回失败审核的函数:
def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResultLight, Seq] = {
auditResultsLight.filterNot(r => r.isSuccessful)
}
代码为https://gist.github.com/wjur/93712a51d392d181ab7fc2408e4ce48b
的要点代码编译并执行,但在我的情况下,问题是我的IDE(IntelliJ)报告了Query[Nothing, Nothing, scala.Seq]
的{{1}}类型。每当我使用auditResultsLight
并在查询中引用auditResultsLight
字段时,我都会收到语法错误。但是,正因为如此,我最终决定使用你建议的第二种方法(带有抽象表的方法)。几乎相同数量的代码,但支持IDE。