2015-09-27 32 views
2

我試圖通過使用操作列表和摺疊列表來將一系列可選的篩選操作應用於查詢。Scala Slick - 將TableQuery [E]轉換爲查詢[E]鏈操作

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] 

基本上簽名,在每個功能,我任選地將過濾如果過濾器參數選項*存在。然而,即使TableQuery是Query的子類型,編譯器也不喜歡我將TableQuery傳遞給接受Query的函數。有沒有辦法將TableQuery轉換爲查詢?或者更好的方法去查詢鏈接過濾函數?

有問題的編譯器錯誤是

類型不匹配;

實測值:scala.slick.lifted.Query [generated.Tables.Farm,generated.Tables.FarmRow,SEQ]

需要:scala.slick.lifted.TableQuery [generated.Tables.Farm]

我可以通過使用table.drop(0)而不是表來編譯它,但顯然這似乎是一個糟糕的解決方法。我看到TableQuery上有一個方法將它轉換爲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) 
} 
+0

您可以添加篩選器的示例嗎? –

+0

對不起,無法弄清楚如何在註釋中發佈代碼以便添加到OP中。 下面的解決方案實際上並不工作,因爲我需要執行連接和過濾器,這取決於我正在應用的「過濾器」的特定特徵,因此它們是功能。 –

回答

0

我想你可以嘗試另一種方法。您可以使用collect來取代Some值,而不是使用fold。 然後,您可以對每個選項應用一個篩選器:

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) 
相關問題