Skip to content

Instantly share code, notes, and snippets.

@werwolfby
Last active September 16, 2024 11:32
Show Gist options
  • Save werwolfby/7f04558bc21c8114e209d5727fb2e9f8 to your computer and use it in GitHub Desktop.
Save werwolfby/7f04558bc21c8114e209d5727fb2e9f8 to your computer and use it in GitHub Desktop.
EF Core DateTime Utc kind
public class CustomDbContext : DbContext
{
// ...
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
// Replace default materializer source to custom, to convert DateTimes
options.ReplaceService<IEntityMaterializerSource, DateTimeKindEntityMaterializerSource>();
base.OnConfiguring(options);
}
}
public class DateTimeKindEntityMaterializerSource : EntityMaterializerSource
{
private static readonly MethodInfo _normalizeMethod =
typeof(DateTimeKindMapper).GetTypeInfo().GetMethod(nameof(DateTimeKindMapper.Normalize));
private static readonly MethodInfo _normalizeNullableMethod =
typeof(DateTimeKindMapper).GetTypeInfo().GetMethod(nameof(DateTimeKindMapper.NormalizeNullable));
private static readonly MethodInfo _normalizeObjectMethod =
typeof(DateTimeKindMapper).GetTypeInfo().GetMethod(nameof(DateTimeKindMapper.NormalizeObject));
public override Expression CreateReadValueExpression(Expression valueBuffer, Type type, int index, IProperty property = null)
{
if (type == typeof(DateTime))
{
return Expression.Call(
_normalizeMethod,
base.CreateReadValueExpression(valueBuffer, type, index, property));
}
if (type == typeof(DateTime?))
{
return Expression.Call(
_normalizeNullableMethod,
base.CreateReadValueExpression(valueBuffer, type, index, property));
}
return base.CreateReadValueExpression(valueBuffer, type, index, property);
}
public override Expression CreateReadValueCallExpression(Expression valueBuffer, int index)
{
var readValueCallExpression = base.CreateReadValueCallExpression(valueBuffer, index);
if (readValueCallExpression.Type == typeof(DateTime))
{
return Expression.Call(
_normalizeMethod,
readValueCallExpression);
}
if (readValueCallExpression.Type == typeof(DateTime?))
{
return Expression.Call(
_normalizeNullableMethod,
readValueCallExpression);
}
if (readValueCallExpression.Type == typeof(object))
{
return Expression.Call(
_normalizeObjectMethod,
readValueCallExpression);
}
return readValueCallExpression;
}
}
public class DateTimeKindMapper
{
public static DateTime Normalize(DateTime value)
=> DateTime.SpecifyKind(value, DateTimeKind.Utc);
public static DateTime? NormalizeNullable(DateTime? value)
=> value.HasValue ? DateTime.SpecifyKind(value.Value, DateTimeKind.Utc) : (DateTime?)null;
public static object NormalizeObject(object value)
=> value is DateTime dateTime ? Normalize(dateTime) : value;
}
@danielGentus
Copy link

Can you make an example using .Net 6?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment