【问题标题】:How to cast datetimeoffset to datetime in entity framework?如何在实体框架中将 datetimeoffset 转换为 datetime?
【发布时间】:2017-04-29 09:03:41
【问题描述】:

这似乎是一件简单的事情,但 EF 不支持像 DateTimeOffset.DateTimeDateTimeOffset.LocalDateTime 甚至 DateTime.Date 这样的属性。我正在尝试仅通过 DateTime 组件(即“本地”DateTime)过滤 DateTimeOffset 类型字段,这在普通 sql 中很简单:where cast(x as datetime) = '2016-12-14'

有一个DbFunctions.TruncateTime,但没有对应的TruncateOffset

似乎没有任何方法可以将DateTimeOffset 对象转换或转换为在linq-to-entities 中工作的普通DateTime 对象。唯一的转换是从DateTimeDateTimeOffset 的隐式转换,但反之则不然。

【问题讨论】:

  • TruncateTime 有两个重载 TruncateTime(Nullable<DateTimeOffset>)TruncateTime(Nullable<DateTime>)
  • 两者都丢弃了时间。我想获取 DateTimeOffset 的 DateTime(日期和时间),而不需要 Offset。如果您无法获取 DateTimeOffset 的 DateTime 部分,那么支持该类型是完全没有用的。 DateTimeOffset 等效于 UTC DateTime,它只是将 DateTime 与 Offset 分开。如果我无法在 EF 中查询 DateTimeOffset 的 DateTime 部分,那就毫无价值了。就像我说的,在普通 SQL 中,它只是 cast(x as datetime) 其中 x 是 DateTimeOffset 字段。他们真的需要一个 TruncateOffset 函数。

标签: entity-framework-6 datetimeoffset


【解决方案1】:

您可以使用 DbFunctions.CreateDateTime 去除偏移量,例如:

...
.Select(e => new MyClass {                                      
  MyDate = DbFunctions.CreateDateTime(e.MyDateTimeOffset.Year,
                                      e.MyDateTimeOffset.Month,
                                      e.MyDateTimeOffset.Day,
                                      e.MyDateTimeOffset.Hour,
                                      e.MyDateTimeOffset.Minute,
                                      e.MyDateTimeOffset.Second)
...

您可能会怀疑,这会创建一些非常糟糕的 SQL,即:

convert (datetime2,right('000' + convert(varchar(255), DATEPART (year, [Extent1].[MyDateTimeOffset])), 4) + '-' + convert(varchar(255), DATEPART (month, [Extent1].[MyDateTimeOffset])) + '-' + convert(varchar(255), DATEPART (day, [Extent1].[MyDateTimeOffset])) + ' ' + convert(varchar(255), DATEPART (hour, [Extent1].[MyDateTimeOffset])) + ':' + convert(varchar(255), DATEPART (minute, [Extent1].[MyDateTimeOffset])) + ':' + str( CAST( DATEPART (second, [Extent1].[MyDateTimeOffset]) AS float), 10, 7), 121) AS [C2]

但是它会给你你想要的。

需要注意的是,这将完全剥离/忽略偏移量(按照 OP 的要求)。

【讨论】:

  • 但这不会将 datetimeoffset 转换为本地 datetime,它只是使用 datetimeoffset 的值。
【解决方案2】:

我与DbFunctions.TruncateTime 有完全相同的问题,并且能够使用DbFunctions.DiffDays 解决它

这是一个例子:

DbFunctions.DiffDays(DateTimeOffset.Now, x.EventDate) == 0

使用 DbFunctions.DiffDays 时,不考虑偏移量。这是 MSDN 文档:https://msdn.microsoft.com/en-us/library/dn220092(v=vs.113).aspx

【讨论】:

  • 这对回答 OP 的问题有何帮助?您是如何从使用 DiffDays 到实际从 DateTimeOffset 中获取 DateTime 组件的?
  • 我曾写过:“使用 DbFunctions.DiffDays 时,不考虑偏移量”。 OP 有一个示例:其中 cast(x as datetime) = '2016-12-14'。您可以使用以下方法解决此问题: DbFunctions.DiffDays('2016-12-14', x.EFTableDate) == 0 .. 这说明清楚了吗?
  • gotcha - 非常有道理 - 我专注于转换为 DateTime 并错过了他希望在 where 子句中使用它。
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 2011-06-24
相关资源
最近更新 更多