用例:编写像
这样的通用函数def tenantFilterQuery[T, Q <: Table[T]](t: Q, e: TableQuery[Q], id: Int)(implicit s: Session) :Query[Q,Q#TableElementType,Seq] = {
e.filter(_.tenantId === id)
}
我正在尝试添加编译时智能,e.filter(_.tenantId === id)
过滤器应仅适用于传递T
存在名为tenantId
的属性,否则它将不会应用该过滤器{} {1}}没有那个属性。
可以使用或不使用无形的相关路径类型来解决这个问题吗?
第二步尝试提出一种方法,即在最终T
生成时Query
具有名为T
的属性,如果它没有,它将在编译时失败'在tenantId
上有filter
。想想我应该在第一个被弄清楚的时候为这个问题创建一个单独的问题。
答案 0 :(得分:0)
第二个问题是更简单的问题:您可以使用结构类型T <: {def tenantId: Int}
,然后只能使用T
来调用它。
如果您希望过滤器针对这些类型发生而不是针对其他类型发生,我想您可以通过提供隐式帮助器来实现此目的吗?类似的东西:
sealed trait Helper[T]{
def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q]
}
trait LowPriorityHelper {
implicit def withoutTenantId[T] = new Helper[T] {
def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] = e
}
}
object Helper extends LowPriorityHelper {
implicit def withTenantId[T <: {def tenantId: Int}] =
new Helper[T] {
def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] =
e.filter(_.tenantId === id)
}
}
def doQuery[T: Helper] = { val e = ...; implicitly[Helper[T]].applyToQuery(e)...}
withTenantId
Helper
将传递给T
的{{1}},否则传递tenantId
。