我有一个名为Campaigns
的对象的数据库,其中包含三个字段:
让我们CampaignsRow
调用相应的光滑实体类
当我从Campaigns中选择一行时,我并不总是需要阅读包含大量文本的内容。
但是,我非常想在代码库中使用CampaignsRow类而不是元组,因此有时可以删除Stuff列,同时保留原始类型
基本上,我正在尝试编写以下函数:
//Force dropping the Stuff column from the current Query
def smallCampaign(campaigns: Query[Campaigns, CampaignsRow, Seq]): Query[Campaigns, CampaignsRow, Seq] = {
val smallCampaignQuery = campaigns.map {
row => CampaignsRow(row.id, row.version , None : Option[String])
}
smallCampaignQuery /* Fails because the type is now wrong, I have a Query[(Rep[Int], Rep[Int], Rep[Option[String]), (Int, Int, Option[String], Seq] */
}
任何想法如何做到这一点?我怀疑这与slick中的Shape有关,但是我找不到资源来开始理解此类,并且slick源代码对于我来说太复杂了。
答案 0 :(得分:2)
实际上,您已经在def *
(默认映射)中几乎完成了所需的操作。您可以在map
方法中使用相同的工具。您的两个工具是mapTo
和<>
。
您已经发现,mapTo
方法仅在您的case类与元组的形状完全匹配时才可以使用,因此,如果您只想为此目的使用特殊case类:>
case class CampaignLite(id: Int, version: Int)
val smallCampaignQuery = campaigns.map {
row => (row.id, row.version).mapTo[CampaignLite]
}
当您要重用现有类时,可以编写自己的转换函数,而不必使用标准的tupled
和unapply
并将其传递给<>
:
object CampaignRow {
def tupleLite(t: (Int, Int)) = CampaignRow(t._1, t._2, None)
def unapplyLite(c: CampaignRow) = Some((c.id, c.version))
}
val smallCampaignQuery = campaigns.map {
row => (row.id, row.version) <> (CampaignRow.tupleLite, CampaignRow.unapplyLite)
}
这为您提供了最大的灵活性,因为您可以在转换函数中做任何您想做的事,但是它比较罗word。
由于row
是Campaigns
表的一个实例,如果需要定期使用它,可以随时在*
旁边定义它。
class Campaigns ... {
...
def * = (id, version, stuff).mapTo[CampaignRow]
def liteMapping = (id, version) <> (CampaignRow.tupleLite, CampaignRow.unapplyLite)
}
val liteCampaigns = campaigns.map(_.liteMapping)
答案 1 :(得分:1)
如果我正确理解了您的要求,则可以考虑使CampaignRow
扩展Campaigns
并提供双向映射,从而使Campaigns
成为为Table[CampaignRow]
表类建模的案例类。用于*
投影:
case class CampaignRow(id: Int, version: Int, stuff: Option[String])
class Campaigns(tag: Tag) extends Table[CampaignRow](tag, "CAMPAIGNS") {
// ...
def * = (id, version, stuff) <> (CampaignRow.tupled, CampaignRow.unapply)
}
然后您应该可以执行以下操作:
val campaigns = TableQuery[CampaignRow]
val smallCampaignQuery = campaigns.map( _.copy(stuff = None) )
举一个相关的例子,这里是Slick doc。