День 2329. #ЗаметкиНаПолях
Используем EF Core для Сохранения Дат в UTC и Отображения в Местном Времени. Начало
Если вы используете Entity Framework Core, вы можете легко сохранять даты в формате UTC в БД, а затем преобразовывать их обратно в местный часовой пояс в приложении ASP.NET Core. Это особенно важно, если ваше приложение охватывает несколько часовых поясов.
ValueConverter
ValueConverter позволяет преобразовывать значение сущности в значение провайдера, например БД SQL Server, а затем преобразовывать его обратно в модель для приложения ASP.NET Core. Так мы можем преобразовывать время в UTC при сохранении в БД, а затем обратно в местный часовой пояс при использовании в приложении.
Нам нужно создать класс, наследующий от ValueConverter. Обобщённый тип ValueConverter в качестве параметров типа типы модели и провайдера. Поскольку мы ожидаем тип DateTime и в БД, и приложении, мы можем использовать его для обоих.
Затем нужно переопределить один из базовых конструкторов ValueConverter, чтобы выполнить преобразование. Он ожидает два параметра:
1. Значение ExpressionFrom, т.е. как вы сохраняете значение в БД. Мы преобразуем значение DateTime в универсальное время.
2. Значение ExpressionTo, т.е. как оно отображается в приложении. Нам нужно указать, что тип DateTime — это UTC (так он сохраняется в БД), а затем нужно преобразовать его в местный часовой пояс.
Вот код нашего DateTimeUtcConverter:
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
public class DateTimeUtcConverter
: ValueConverter<DateTime, DateTime>
{
public DateTimeUtcConverter() : base(
d => d.ToUniversalTime(),
d => DateTime
.SpecifyKind(d, DateTimeKind.Utc)
.ToLocalTime()
)
{}
}
Применение
У нас есть такая сущность Product, установленная в DbContext:
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public DateTime Created { get; set; }
}
При создании новой сущности Product в БД, если бы мы установили свойство Created на DateTime.Now, это сохранило бы DateTime в БД с использованием локального часового пояса приложения. Это стало бы проблемой, если бы вы когда-либо изменили часовой пояс для своего приложения.
Но настройка сущности Product позволяет нам указать класс DateTimeUtcConverter в методе расширения HasConverter. Это гарантирует, что свойство Created будет сохранено как UTC в БД и преобразовано обратно в локальный часовой пояс при использовании в приложении:
public class ProductConfiguration
: IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> b)
{
b.HasKey(s => s.Id);
b.Property(s => s.Created)
.HasColumnName("CreatedUtc")
.HasColumnType("datetime")
.HasConversion(new DateTimeUtcConverter());
}
}
Окончание следует…
Источник: https://www.roundthecode.com/dotnet-tutorials/use-ef-core-easily-save-dates-utc-show-local-time
>>Click here to continue<<