Проблему удалось решить так:
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Domain.ValueConversion
{
public static class EntityFrameworkCoreModelBuilderExtensions
{
public static void AddDateTimeOffsetConverter(this ModelBuilder builder)
{
// SQLite does not support DateTimeOffset
foreach (var property in builder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(DateTimeOffset)))
{
property.SetValueConverter(
new ValueConverter<DateTimeOffset, DateTime>(
convertToProviderExpression: dateTimeOffset => dateTimeOffset.UtcDateTime,
convertFromProviderExpression: dateTime => new DateTimeOffset(dateTime)
));
}
foreach (var property in builder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(DateTimeOffset?)))
{
property.SetValueConverter(
new ValueConverter<DateTimeOffset?, DateTime>(
convertToProviderExpression: dateTimeOffset => dateTimeOffset.Value.UtcDateTime,
convertFromProviderExpression: dateTime => new DateTimeOffset(dateTime)
));
}
}
public static void AddDateTimeUtcKindConverter(this ModelBuilder builder)
{
// If you store a DateTime object to the DB with a DateTimeKind of either `Utc` or `Local`,
// when you read that record back from the DB you'll get a DateTime object whose kind is `Unspecified`.
// Here is a fix for it!
var dateTimeConverter = new ValueConverter<DateTime, DateTime>(
v => v.Kind == DateTimeKind.Utc ? v : v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
var nullableDateTimeConverter = new ValueConverter<DateTime?, DateTime?>(
v => !v.HasValue ? v : (v.Value.Kind == DateTimeKind.Utc ? v : v.Value.ToUniversalTime()),
v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v);
foreach (var property in builder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties()))
{
if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(dateTimeConverter);
}
if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(nullableDateTimeConverter);
}
}
}
}
}
Источник,
Лицензия
using Microsoft.EntityFrameworkCore;
using MySql.Data.EntityFrameworkCore.Extensions;
namespace Infrastructure.Data.Contexts
{
/// <summary>
/// Контекст для работы с БД событий.
/// </summary>
public class SystemEventContext : DbContextEx
{
public DbSet<SystemEvent> Events { get; set; }
public SystemEventContext(DbContextOptions<SystemEventContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
const string TIMESTAMP_COLUMN_TYPE = "timestamp(3)";
// ...
base.OnModelCreating(builder);
// ...
builder.AddDateTimeOffsetConverter();
builder.AddDateTimeUtcKindConverter();
}
}
}