首页 > 解决方案 > 实体框架 LINQ 调用 switchoffset() 函数

问题描述

我有一个表,其中一列是 datetimeoffset 类型。我在使用EF Core,如何调用sql内置函数switchoffset()?我已经有了用户的时区值,但不知道如何调用此函数将 datetimeoffset 值转换为用户自己的时间。

我试过“SqlFunctions”,没有这样的功能可用。

谢谢!

标签: linqentity-framework-core

解决方案


1.在静态类中添加自定义/内置函数

    public static class CustomFunctions
    {
        public static DateTime ChangeTimeZoneOffset(this DateTime datetime, string timeZoneOffset)
        {
            throw new NotSupportedException();
        }
        public static DateTime ChangeTimeZoneOffset(this DateTime datetime, int timeZoneOffset)
        {
            throw new NotSupportedException();
        }
        public static string Format(this DateTime datetime, string format)
        {
            throw new NotSupportedException();
        }
        public static string Format(this DateTime datetime, string format, string culture)
        {
            throw new NotSupportedException();
        }
    }

2. 正确映射这些函数:

modelBuilder.HasDbFunction(typeof(CustomFunctions).GetMethod(nameof(CustomFunctions.ChangeTimeZoneOffset), new[] { typeof(DateTime), typeof(string) }))
                .HasName("SwitchOffset").IsBuiltIn();

modelBuilder.HasDbFunction(typeof(CustomFunctions).GetMethod(nameof(CustomFunctions.ChangeTimeZoneOffset), new[] { typeof(DateTime), typeof(int) }))
                .HasName("SwitchOffset").IsBuiltIn();

modelBuilder.HasDbFunction(typeof(CustomFunctions).GetMethod(nameof(CustomFunctions.Format), new[] { typeof(DateTime), typeof(string) }))
                .HasName("Format").IsBuiltIn();

modelBuilder.HasDbFunction(typeof(CustomFunctions).GetMethod(nameof(CustomFunctions.Format), new[] { typeof(DateTime), typeof(string), typeof(string) }))
                .HasName("Format").IsBuiltIn();

3. 在你的 LINQ 中使用它:

    ...
    .Select(i => new
    {
        TheDateTimeInUserTimeZone = CustomFunctions.ChangeTimeZoneOffset(i.MyDateTime, timeZoneOffsetVariable)
    }

如果您的时区偏移量是静态的(例如您的用户国家/地区是静态的,但日期时间存储在 UTC 中),一种解决方案是使用计算列:

entity.Property(e => e.TheDateTimeInIRIran).HasComputedColumnSql("(SWITCHOFFSET([MyDateTime], '+03:30'))", false);

您也可以将日期从 greg 转换为 jalali,例如:

entity.Property(e => e.TheDateTimeInIRIran).HasComputedColumnSql("(FORMAT(SWITCHOFFSET([MyDateTime], '+03:30'), 'yyyy/MM/dd HH:mm:ss', 'fa-ir'))", false);

或使用At Time Zone支持夏令时的子句 (SQL Server 2016+)。


推荐阅读