2014-10-31 31 views
3

我有以下表定義(簡化):如何使用inSetBind篩選Slick中的多個列?

class Houses(tag: Tag) extends Table[HouseRow](tag, "HOUSE") { 
    def houseId = column[Long]("HOUSE_ID", O.NotNull, O.PrimaryKey, O.AutoInc) 
    def houseName = column[String]("HOUSE_NAME", O.NotNull) 
    def houseType = column[String]("HOUSE_TYPE", O.NotNull) 

    def uniqueHouseName = index("UQ_HOUSE_NAME_HOUSE_TYPE", (houseName, houseType), true) 

    def * = (houseId, houseName, houseType) <> (HouseRow.tupled, HouseRow.unapply) 
} 

val houses = TableQuery[Houses] 

我想選擇的一組的索引uniqueHouseName的匹配進行如下的房屋。

case class HouseKey(houseName: String, houseType: String) 
val houseKeys: Seq(HouseKey("name1", "type1"), HouseKey("name2", "type2")) 

一個天真的inSetBind過濾器將匹配例如。 HouseRow(ID, "name1", "type2")這是錯誤的。 MySQL中我會做這樣的事情:

SELECT * FROM HOUSE h 
WHERE(h.HOUSE_TYPE, d.HOUSE_NAME) IN 
(
    SELECT 'type1' as HOUSE_TYPE, 'name1' as HOUSE_NAME 
    UNION 
    SELECT 'type2', 'name2' 
); 

回答

1

適應tuxdna的答案允許任意seqs。但是,此查詢可能不會預編譯爲SQL,並具有運行時開銷。

val filteredHouses = 
    houses.filter(h => 
    houseKeys.map(hk => h.houseName === hk.houseName && h.houseType === hk.houseType) 
       .reduce(_ || _) 
) 
+0

只是一個警告,'減少'在空的列表上爆炸。 – 2014-11-03 21:56:48

0

這不是完整的答案,但只有兩對值,你可以這樣做:

val filteredHouses = for { 
     h <- houses 
     if (h.houseName === "name1" && h.houseType === "type1") || (
     h.houseName === "name2" && h.houseType === "type2") 
    } yield h 
+0

事實上測試。儘管我正在努力與任意對... – 2014-11-02 19:18:54

2

像@cvogt版本,但空單上不炸掉:

val filteredHouses = 
    houses.filter(h => 
    houseKeys.map(hk => h.houseName === hk.houseName && 
     h.houseType === hk.houseType) 
     .reduceOption(_ || _).getOrElse(false: Rep[Boolean]) 
) 

在光滑3.1.0