【发布时间】:2016-11-24 13:42:39
【问题描述】:
如何使用 Entity Framework 中的 MSSQL 2016 AT TIMEZONE 功能?
也就是说,如何生成
SELECT MyTimestamp AT TIME ZONE 'Central European Standard Time' FROM MyTable
通过实体框架中的 LINQ ?它甚至还支持吗?是否可以为此功能手动扩展实体框架?
始终可以选择使用时区列创建数据库视图,但理想情况下,我希望避免这种额外的视图。
【问题讨论】:
-
AT TIMEZONE对于以前根本无法从应用程序代码执行此操作的 T-SQL 程序员来说是一种福音。在 .NET 中,有很好的时区支持可以避免这种情况,因为您始终可以使用TimeZoneInfo.ConvertTime将DateTime或DateTimeOffset转换为任何所需的时区。我并不是说没有需要这样做,但是如果您可以对结果进行任何类型的处理,那么至少有一种解决方法。 -
如果要扩展 EF,它实际上可以转换
TimeZoneInfo.ConvertTime或(更有可能)在SqlFunctions中实现一个新方法。不过,我不认为作为 EF 的客户可以做到这一点。您可以为AT TIMEZONE编写自己的标量值函数并调用它,但由于优化器讨厌标量值函数,所以这样做很蹩脚且效率低下。 -
@JeroenMostert 关于您的第二条评论,我得出了相同的结论。不幸的是不是我希望的答案。
-
@JeroenMostert 我想使用 SQL 时区功能的原因是由于对数据进行了一些分组,这应该在时区转换之后执行(按天分组)。在数据库上执行这些(简单)聚合可以节省大量数据传输开销。
-
如果 EF 没有支持,你必须在数据库中做,它仍然可以通过表值函数合理有效地完成。这仍然很蹩脚,但至少它很快(ish)。
CREATE FUNCTION dbo.AtTimeZone(@d DATETIMEOFFSET, @TimeZone SYSNAME) RETURNS TABLE AS RETURN SELECT @d AT TIME ZONE @TimeZone AS AtTimeZone;EF 5+ 支持 TVF,虽然我不知道它是否可以正确地CROSS APPLY。当然,视图更简单(如您所建议的),但仅适用于一个特定查询。最后但同样重要的是,你当然可以open an issue。
标签: sql-server entity-framework linq sql-server-2016