我正在使用 ASP.NET MVC 5 编写应用程序。我要存储在数据库中的所有日期时间必须先从本地时区转换为 UTC 时区。
我不确定在请求周期内哪里是最好的地方。
在通过 ViewModel 规则后,我可以在 Controller 中将每个字段转换为 UTC。但我觉得我必须做的代码/步骤太多了。
Entity Framework 中是否有一种方法允许我添加一条规则,在保存更改之前自动将日期时间转换为 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;
}
最佳答案
Is there a way in Entity Framework that will allow me to add a rule that automatically converts datetime to UTC before saving the changes?
您可以覆盖 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;
}
}
}
}
您需要添加自己的逻辑,以确保不会出现非用户更改 DateTime 的情况(即确保默认情况下您的物化 DateTime 具有 DateTimeKind.Utc 标志set 或 .Local(如果您为用户更改它)。
编辑
DbContext 还需要访问其运行所在的请求上下文的用户配置文件上的时区。也许 SaveChanges 的重载更适合,因此您可以将其传入,或者如果您正在使用 DI,也许您可以将其注入(inject)到创建的 DbContext 中。
关于c# - Entity Framework 能否在保存时自动将日期时间字段转换为 UTC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39418323/