【发布时间】:2017-07-12 01:13:22
【问题描述】:
我一直在学习 scala、playframework 和 slick,但是我发现了一个问题。 我正在尝试制作一个简单的 CRUD,其中包含一个接收自定义过滤器字段的列表控制器、一些分页信息(页面大小和数量)以及带有字段名称和顺序(asc 或 desc)的字符串元组的 Seq,以及所有内容工作正常,除了按 seq 排序,我不能按动态排序。
我从Scadiddle blog 获得了基本结构。 所以,基本代码如下:
我有我的基本颜色模型:
case class Color(
id: Int,
name: String)
这是一个简单的表定义:
class ColorsTable(tag: Tag) extends Table[Color](tag, "color") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name) <> ((Color.apply _).tupled, Color.unapply)
}
在我的仓库中,我有搜索方法:
def findAll(searchTerm: Option[String], page: Int, top: Int, sortsBy: Seq[(String, SortDirection)]): Future[Seq[Color]] = {
var query = searchTerm match {
case Some(term) => colors.filter(_.name like s"%$term%")
case _ => colors
}
val offset = (page - 1) * top
// This is building the sort clause, matching on each column in the sort
sortsBy.foreach {
sortTuple =>
val (sortColumn, sortDirection) = sortTuple
query = query.sortBy(sortColumn match {
case "id" => if (sortDirection == Desc) _.id.desc else _.id.asc
case _ => if (sortDirection == Desc) _.name.desc else _.name.asc
})
}
// The "list" method actually executes the query
val colorsQuery = query.drop(offset).take(top).result
db.run(colorsQuery)
}
问题是,当我用这个序列调用搜索方法时:
val sortsBy = Seq[(String, SortDirection)](("name", Desc), ("id", Asc))
colorService.getColors(None, 1, 10, sortsBy).map(colorList => Ok(Json.toJson(colorList)))
已生成此查询:
select "id", "name" from "color" order by "id", "name" desc limit 10 offset 0
如您所见,sortBy 的顺序颠倒了(id 然后是 name,而不是 name 和 id 作为顺序)。
如果我使用元组而不是 foreach,则遵守顺序:
query = query.sortBy(
s => (s.name.desc, s.id.asc)
)
但是没有办法生成 dynamic-size 元组。为了增加一些混乱,另一个给我带来麻烦的事情是光滑文档中的this part:
请注意,包含多个列的单个 ORDER BY 不是 相当于多个 .sortBy 调用,但相当于一个 .sortBy 调用 传递一个元组
那么,实际上我可以使用 foreach 并连接订单吗?还是因为这个限制,顺序被颠倒了?
如果只有元组可以用于 sortBy,我如何实现动态大小的 order by?
PD:感谢您的关注,抱歉英语不好
编辑:
感谢您的快速响应,我尝试了您的代码并且看起来不错,遗憾的是我几乎不知道它是如何工作的:((scala 是一种非常好的语言,但很难学习:S)。
当我看到Higher Kinded Type Should be Enabled 时,我吓坏了,寻找答案this 并没有给我带来简单理解的希望,希望当我完成《Scala 编程》第三版时,我会有更多的理解和知道到底发生了什么。
再问一个问题,这是否等同于进行多次 sortBy 调用?这与使用元组相比如何?我仍然对光滑文档的这一部分感到困惑:
具有多个列的单个 ORDER BY 不等同于多个 .sortBy 调用,而是一个传递元组的单个 .sortBy 调用
我检查了我的方法,并通过在 seq 中添加反向使其工作正常,当然不像 功能性 和你的代码一样好,所以我将使用你的建议并努力解决使用助手制作其余的过滤器并避免使用变量。 (是的,在另一部分我仍在使用 var,但当我了解更多 Scala 时,我会做得更好。
自白:在使用多种语言(从 JavaScript 到 Java、C#、Python 等)编程超过 8 年之后,我不得不重复一遍,Scala 看起来是一门漂亮但非常复杂的语言,但我不会放弃学习它
【问题讨论】: