Scala 有条件地将可为null的字段映射到平滑中的无值

Scala 有条件地将可为null的字段映射到平滑中的无值,scala,group-by,option,slick,Scala,Group By,Option,Slick,在Slick 2.1中,我需要执行一个查询/映射操作,如果一个可空字段包含某个非空值,则将其转换为无。不确定这是否重要,但在我的例子中,所讨论的列类型是映射的列类型。下面是一段代码片段,试图说明我要做的事情。它不会编译,因为编译器不喜欢None case class Record(field1: Int, field2: Int, field3: MyEnum) sealed trait MyEnum val MyValue: MyEnum = new MyEnum { } // table

在Slick 2.1中,我需要执行一个查询/
映射
操作,如果一个可空字段包含某个非空值,则将其转换为无。不确定这是否重要,但在我的例子中,所讨论的列类型是映射的列类型。下面是一段代码片段,试图说明我要做的事情。它不会编译,因为编译器不喜欢
None

case class Record(field1: Int, field2: Int, field3: MyEnum)

sealed trait MyEnum
val MyValue: MyEnum = new MyEnum { }

// table is a TableQuery[Record]
table.map { r => (
  r.field1,
  r.field2,
  Case If (r.field3 === MyValue) Then MyValue Else None // compile error on 'None'
  )
}
错误如下所示:

type mismatch; found : None.type required: scala.slick.lifted.Column[MyEnum]
实际上,我想这样做的原因是我想执行一个
groupBy
,其中我计算
field3
包含给定值的记录数。我无法让更复杂的
groupBy
表达式工作,因此我退回到这个更简单的示例,但仍然无法工作。如果有更直接的方法向我显示
groupBy
表达式,那也可以。谢谢

更新

我尝试了@cvogt建议的代码,但这会产生编译错误。这是一个案例,任何人都可以发现我做错了什么。编译失败,因为“value”不是Int的成员:


您需要将MyValue包装在一个选项中,以便条件的两个结果都是选项。在Slick 2.1中,您使用。?接线员。在Slick 3.0中,它可能是Rep.Some(…)

试一试


您需要将MyValue包装在一个选项中,以便条件的两个结果都是选项。在Slick 2.1中,您使用。?接线员。在Slick 3.0中,它可能是Rep.Some(…)

试一试

我需要执行一个查询/映射操作,如果某个字段包含某个非null值,则将该字段转换为None

根据更新中的示例数据,假设
1
是您关心的“确定”值,我相信这就是您期望的输出:

None, None, Some(4)
(对于ID为1、2和3的行)

如果我正确理解了这个问题,这就是你需要的吗

val q: Query[Column[Option[Int]], Option[Int], Seq] = exp.map { record => 
  Case If (record.value === 1) Then (None: Option[Int]) Else (record.value)
}
…相当于:

select (case when ("VALUE" = 1) then null else "VALUE" end) from "EXP"
我需要执行一个查询/映射操作,如果某个字段包含某个非null值,则将该字段转换为None

根据更新中的示例数据,假设
1
是您关心的“确定”值,我相信这就是您期望的输出:

None, None, Some(4)
(对于ID为1、2和3的行)

如果我正确理解了这个问题,这就是你需要的吗

val q: Query[Column[Option[Int]], Option[Int], Seq] = exp.map { record => 
  Case If (record.value === 1) Then (None: Option[Int]) Else (record.value)
}
…相当于:

select (case when ("VALUE" = 1) then null else "VALUE" end) from "EXP"

这两个我都试过了,但都无法编译。我得到“value?不是MyEnum的成员”。我试图通过使用选项[Int]而不是选项[MyEnum]来进一步简化示例,但我得到了相同的编译错误(“value?不是Int的成员”)。我已经导入了驱动程序。很简单。\所以不确定还需要什么才能让“?”正常工作。对。。。您还需要告诉Slick如何映射MyEnum。请参阅“请保持我的帖子”是的,我已经定义了一个映射列类型,如我在最初的帖子中所述。还有,你看到我最近的更新了吗?即使使用一个简单的列[Int],我也无法使用“.”。我一定错过了一些非常简单的东西。错误消息会很有帮助。尝试向上转换到正确的选项类型,这很可能是关于我提供的更新中显示的代码的问题,我在IDE中得到的编译器错误消息是“value?不是Int的成员”。对不起,我不确定我应该向上投射什么。想对更新中的代码发表评论吗?我尝试了这两种方法,但都无法编译。我得到“value?不是MyEnum的成员”。我试图通过使用选项[Int]而不是选项[MyEnum]来进一步简化示例,但我得到了相同的编译错误(“value?不是Int的成员”)。我已经导入了驱动程序。很简单。\所以不确定还需要什么才能让“?”正常工作。对。。。您还需要告诉Slick如何映射MyEnum。请参阅“请保持我的帖子”是的,我已经定义了一个映射列类型,如我在最初的帖子中所述。还有,你看到我最近的更新了吗?即使使用一个简单的列[Int],我也无法使用“.”。我一定错过了一些非常简单的东西。错误消息会很有帮助。尝试向上转换到正确的选项类型,这很可能是关于我提供的更新中显示的代码的问题,我在IDE中得到的编译器错误消息是“value?不是Int的成员”。对不起,我不确定我应该向上投射什么。是否要对更新中的代码进行注释?这基本上是正确的(您混淆了then/else子句,但这只是一个小细节)。我知道我错过了一些简单的事情,男孩就是这么简单。总之,在“Then”子句中,编译器不希望我们将“value”(或“value.?)与“None”混合,因此关键的细节是将“record.value”(已经是一列[Option[Int]])与“None”混合。谢谢这基本上是正确的(您混淆了then/else子句,但这只是一个小细节)。我知道我错过了一些简单的事情,男孩就是这么简单。总之,在“Then”子句中,编译器不希望我们将“value”(或“value.?)与“None”混合,因此关键的细节是将“record.value”(已经是一列[Option[Int]])与“None”混合。谢谢