Scala / Slick:区分联盟内的项目

时间:2014-02-19 00:04:40

标签: scala slick

如何将这两个Coffee个查询合并为一个,并指出它是coffee还是otherCoffee

代码:

protected lazy val coffeeQuery = for {
    id <- Parameters[Long]
    coffee <- CoffeesTable if coffee.userId === id
} yield (coffee)

protected lazy val otherCoffeeQuery = for {
    id <- Parameters[Long]
    employment <- EmployeesTable if employment.employedId === id
    sup <- SuppliersTable if employment.supId === sup.id
    coffee <- CoffeesTable if (coffee.userId === id || coffee.userId === sup.userId)
} yield (otherCoffee)

现在我想获得一份咖啡和咖啡清单。区分是otherCoffee还是<{1}}:

def coffeeList(userId: Long): JValue =  withSession { implicit db: Session =>
    val coffee = coffeeQuery(userId)
    val otherCoffee = otherCoffeeQuery
    val coffeeUnion = coffee union otherCoffee
    // How would I efficiently distinguish which item is "coffee" and which is "otherCoffee"?
    ("coffee" -> 
        coffeeUnion.map { c =>
           ("name" -> c.name) ~
           ("coffee_or_other_coffee" -> // is this coffee or otherCoffee?
        }
    )
}

我愿意采取其他方式解决这个问题(不一定是工会)

1 个答案:

答案 0 :(得分:2)

您可以将查询结果映射到包含以下内容的元组: 'coffee / 'otherCoffee(或true / false等)

val coffee = Set(coffeeQuery(userId):_*)
val otherCoffee = Set(otherCoffeeQuery:_*)
val coffeeUnion = coffee.map(_ -> 'coffee) ++ otherCoffee.filterNot(coffee.contains(_)).map(_ -> 'otherCoffee)
// coffeeUnion is a Set[Tuple2[Coffee, Symbol]]; you can make this e.g. a Set[Tuple2[Coffee, String]] instead via
// coffee.map(_ -> "coffee") ++ otherCoffee.filterNot(coffee.contains(_)).map(_ -> "otherCoffee")
("coffee" ->
  coffeeUnion.map { tuple =>
    ("name" -> tuple._1.name) ~
    ("coffee_or_other_coffee" -> tuple._2)

您不需要使用Sets,但与使用filterNot

相比,它们会使Seqs更快

您也可以使用Sets无元组

来执行此操作
val coffee = Set(coffeeQuery(userId):_*)
val otherCoffee = Set(otherCoffeeQuery:_*)
val coffeeUnion = coffee union otherCoffee
("coffee" ->
  coffeeUnion.map { c =>
    ("name" -> c.name) ~
    ("coffee_or_other_coffee" -> if(coffee.contains(c)) 'coffee else 'otherCoffee)