实体框架可以在保存时自动将日期时间字段转换为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保存更改之前?
您可以覆盖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中。