实体框架可以在保存时自动将日期时间字段转换为UTC吗?

本文关键字:字段 时间 日期 转换 UTC 框架 保存 实体 | 更新日期: 2023-09-27 18:06:28

我正在使用ASP编写应用程序。asp.net MVC 5。我要存储在数据库中的所有datetime必须首先从本地时区转换为UTC时区。

我不确定在请求周期中哪里是最好的地方。

我可以在它通过ViewModel规则后将控制器中的每个字段转换为UTC。但是我觉得我要做的代码/步骤太多了。

是否有一种方法在实体框架,将允许我添加一个规则,自动转换日期时间到UTC保存更改之前?

这是我编写的将给定日期时间转换为UTC的方法

public static DateTime? ConvertToUTC(DateTime? val, TimeZoneInfo destinationTimeZone = null)
{
        if (val != null)
        {
            var dateTimeToConvert = ConvertToDateTime(val);
            if (destinationTimeZone == null)
            {
                if (ConfigurationManager.AppSettings["LocalTimeZone"] != null)
                {
                    destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["LocalTimeZone"]);
                }
                else
                {
                    destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(TimeZone.CurrentTimeZone.StandardName);
                }
            }
            return TimeZoneInfo.ConvertTimeFromUtc(dateTimeToConvert, destinationTimeZone);
        }
        return null;
}

实体框架可以在保存时自动将日期时间字段转换为UTC吗?

是否有一种方法在实体框架,将允许我添加一个规则,自动转换日期时间到UTC保存更改之前?

您可以覆盖SaveChanges/SaveChangesAsync方法,并在DbContext上调用它们之前执行转换。

// on your DbContext type
public override int SaveChanges(){
    DateTimeUtcHelper.SetDatesToUtc(this.ChangeTracker.Entries());
    return base.SaveChanges();
}
class DateTimeUtcHelper{
    internal static void SetDatesToUtc(IEnumerable<DbEntityEntry> changes) {
        foreach (var dbEntry in changes.Where(x => ChangesToTrackList.Contains(new[] {EntityState.Added, EntityState.Modified}))){
            foreach (var propertyName in dbEntry.CurrentValues.PropertyNames){
                // using reflection add logic to determine if its a DateTime or nullable DateTime
                // && if its kind = DateTimeKind.Local or Unspecified
                // and then convert set the Utc value
                // and write it back to the entry using dbEntry.CurrentValues[propertyName] = utcvalue;
            }
        }
    }
}

您需要添加自己的逻辑,以确保没有实例中,您正在更改的日期时间,而不是来自用户(即。确保在默认情况下,你的具体化日期时间有DateTimeKind。Utc标志设置或. local(如果您为用户更改它)。


编辑

DbContext还需要访问它所运行的请求上下文的用户配置文件上的时区。也许SaveChanges的过载会更适合,所以你可以在OR中传递它,如果你使用DI,也许你可以将它注入到创建的DbContext中。

相关文章: