我正在尝试通过使用操作列表并将其折叠到查询中,对查询应用一系列可选的过滤操作。

val table = TableQuery[Fizz]
val filters = List(filter1(option1)_, filter2(option2)_, filter3(option3)_)
val filteredQuery = filters.foldLeft(table){(q, filter) => filter(q)}


部分应用的过滤器功能具有以下特征

Query[Fizz, FizzRow, Seq] => Query[Fizz, FizzRow, Seq]


基本上,在每个函数中,如果存在filter参数option *,我都可以选择应用过滤。但是,编译器不喜欢我将TableQuery传递给采用Query的函数的事实,即使TableQuery是Query的子类型。有没有一种方法可以将TableQuery转换为Query?还是在查询上链接过滤器函数的更好方法?

有问题的编译器错误是

类型不匹配;

找到:scala.slick.lifted.Query [生成.Tables.Farm,生成.Tables.FarmRow,Seq]

必需:scala.slick.lifted.TableQuery [generate.Tables.Farm]

我可以使用table.drop(0)代替table进行编译,但是显然这是一个较差的解决方法。我看到TableQuery上有一个to方法可以将其转换为Query,但它也需要一个隐式ctc:TypedCollectionTypeConstructor [D]。

上面列出的filterX函数之一的示例:

def filterCharacteristics(characteristics: Option[List[Int]])(table: Query[Farm,FarmRow,Seq]) = {
characteristics.map(chars =>
  (for {
    (fc, f) <- Farmcharacteristic.filter(_.characteristicId inSet chars) join table on (_.farmId === _.farmId)
  } yield f)).getOrElse(table)
}

最佳答案

我认为您可以尝试另一种方法。除了使用fold,还可以使用collect仅获取Some值。
然后,您可以将过滤器应用于您拥有的每个选项:

val table = TableQuery[Fizz]
val filteredQueries = List(Some(option1), Some(option2), Some(option3)) collect {
  case Some(option) => option
} map { currentOption =>
  table.filter(currentOption)
}

// We need to get the last value or the TableQuery
val lastValue = filteredQueries reverse headOption

// Or we have Some(Query) or None, In case it is a None, we will use table
lastValue.getOrElse(table)

关于scala - Scala Slick-将TableQuery [E]转换为Query [E]以进行链式操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32811122/

10-10 21:40