我正在尝试创建一个等同于select ... where owner_id in (select ...)
的Slick查询。问题是owner_id
是一个多态键,我们的表id是键入的。
class Id[+M](val value: Long) extends MappedTo[Long]
我想写一个这样的查询:
val Apples: Query[ApplesTable, Apple, Seq] = ...
val Farmers: Query[FarmersTable, Farmer, Seq] = ...
Apples.filter(apple =>
apple.ownerType === "FARMER" &&
apple.ownerId.in(Farmers.map(_.id))
)
此操作失败,因为所有者定义为val ownerId = column[Option[Long]](...)
,因此apple.ownerId.in
需要实体类型为Long
的查询,而Farmers.map(_.id)
则返回Id[Farmer]
类型的实体}。
有没有办法将Query[FarmersTable, Id[Farmer], Seq]
类型的查询转换为Query[FarmersTable, Long, Seq]
类型的查询?
鉴于Query.map
方法的签名(下面),我认为解决方案在于构建一个正确的Shape
实例。但是,我找不到合适的工厂。
/** Build a new query by applying a function to all elements of this query. */
def map[F, G, T](f: E => F)(implicit shape: Shape[_ <: FlatShapeLevel, F, T, G]): Query[G, T, C] =
flatMap(v => Query[F, T, G](f(v)))
更新
ownerId
被输入Option[Long]
,因为它可以为空,我们希望根据ownerType
(例如case class Farmer(id: Id[Farmer], ...)
或case class HungryJerry(id: Id[HungryJerry], ...)
加入不同的模型。