【问题标题】:How to convert microsoft.sql.DateTimeOffset to Date in Anorm?如何将 microsoft.sql.DateTimeOffset 转换为 Anorm 中的日期?
【发布时间】:2015-02-25 10:45:15
【问题描述】:

我正在开发一个使用 Scala、Play 框架 2.3.8、Anorm 开发的项目,并使用 MS SQL 数据库。

代码如下:

val repeatedCardsQuery = SQL("Execute Forms.getListOfRepeatCalls {user}, {cardId}")
DB.withConnection { implicit c =>
  val result = repeatedCardsQuery.on("user" -> user.name, "cardId" -> id)().map(row =>
    Json.obj(
      "Unified_CardNumber" -> row[Long]("scId"),
      "ContentSituation_TypeSituationName" -> row[String]("typeOfEventsName"),
      "Unified_Date" -> row[Date]("creationDate"),
      "InfoPlaceSituation_Address" -> row[String]("address"),
      "DescriptionSituation_DescriptionSituation" -> row[Option[String]]("description")
    )
  ).toList
  Ok(response(id, "repeats", result))
}

它给了我运行时错误:

play.api.Application$$anon$1: Execution exception[[RuntimeException: Left(TypeDoesNotMatch(Cannot convert 2015-02-14 15:38:15.4089363 +03:00: class microsoft.sql.DateTimeOffset to Date for column ColumnName(.creationDate,Some(creationDate))))]]
    at play.api.Application$class.handleError(Application.scala:296) ~[play_2.10-2.3.8.jar:2.3.8]
    at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.10-2.3.8.jar:2.3.8]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.10-2.3.8.jar:2.3.8]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.10-2.3.8.jar:2.3.8]
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) [scala-library.jar:na]
Caused by: java.lang.RuntimeException: Left(TypeDoesNotMatch(Cannot convert 2015-02-14 15:38:15.4089363 +03:00: class microsoft.sql.DateTimeOffset to Date for column ColumnName(.creationDate,Some(creationDate))))
    at anorm.MayErr$$anonfun$get$1.apply(MayErr.scala:34) ~[anorm_2.10-2.3.8.jar:2.3.8]
    at anorm.MayErr$$anonfun$get$1.apply(MayErr.scala:33) ~[anorm_2.10-2.3.8.jar:2.3.8]
    at scala.util.Either.fold(Either.scala:97) ~[scala-library.jar:na]
    at anorm.MayErr.get(MayErr.scala:33) ~[anorm_2.10-2.3.8.jar:2.3.8]
    at anorm.Row$class.apply(Row.scala:57) ~[anorm_2.10-2.3.8.jar:2.3.8]
[error] application - Left(TypeDoesNotMatch(Cannot convert 2015-02-14 15:38:15.4089363 +03:00: class microsoft.sql.DateTimeOffset to Date for column ColumnName(.creationDate,Some(creationDate))))

其实就是在这一行出现了错误:

"Unified_Date" -> row[Date]("creationDate"),

如何解决这个问题,在这种情况下将 microsoft.sql.DateTimeOffset 转换为 Date?

【问题讨论】:

  • 如果你使用"Unified_Date" -> new Date(row[microsoft.sql.DateTimeOffset]("creationDate").getTimestamp)会怎样?我知道它不漂亮,但只是看看它是否有效......
  • 你也可以尝试创建一个隐式转换器,如implicit def MSSQLDTOffset2Date(value : microsoft.sql.DateTimeOffset) = new Date(value.getTimestamp) 并查看 anorm 是否选择它
  • @Salem 第一个变体不起作用,因为异常的最后更改需要类型安全参数。更多内容:playframework.com/documentation/2.3.x/Migration23#Anorm 创建隐式转换器可能有效,但异常如何选择它?在这段代码中我需要在哪里声明隐含转换器?
  • 通常您会在一个对象中定义它,然后在需要时导入该 obj。要对其进行测试,您可以在 repeatedCardsQuery 或该文件中可能需要它的任何其他查询之前声明它

标签: sql-server anorm


【解决方案1】:

可以在您的 Anorm 调用旁边添加自定义列转换(在需要支持此类类型的同一类/对象中定义或导入)。

import java.util.Date
import microsoft.sql.DateTimeOffset
import anorm.Column

implicit def columnToDate: Column[Date] = Column.nonNull { (value, meta) => 
  val MetaDataItem(qualified, nullable, clazz) = meta
  value match {
    case ms: DateTimeOffset =>
      Right(ms.getTimestamp)
    case _ => 
      Left(TypeDoesNotMatch(s"Cannot convert $value: ${value.asInstanceOf[AnyRef].getClass} to Boolean for column $qualified"))
  }
}

顺便说一句,使用表示为 JDBC 日期(Anorm 支持的java.sql.Date 类型)的 DB 值会更好。

【讨论】:

  • 我认为这是正确的方法。但是该代码无法编译。想法建议我:'类型不匹配,预期:(​​Any,MetaDataItem)=> MayErr [SqlRequestError,NotInferedA],实际:(Any,MetaDataItem)=> Unit'以'{(value,meta)...'开头,并且播放编译器告诉同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 2011-04-14
  • 2010-11-03
  • 2020-03-19
  • 2012-08-12
  • 2019-06-14
  • 1970-01-01
相关资源
最近更新 更多