DateTime SpecifyKind in Entity Framework Core While Querying

DateTime SpecifyKind in Entity Framework Core While Querying

When you query an entity with a DateTime property via Entity Framework, Kind of DateTime properties are always Unspecified, because DateTime can not store time zone information in the database. However, we may want to use DateTime to store UTC dates in the database by convention and we may want to set Kind to UTC by default while querying from database.

In Entity Framework 6.x, we had ObjectMaterialized event to intercept querying and change Kind of DateTime properties. But Entity Framework Core does not provide a way of that. See related issue: It will be probably implemented in the future (, but we have a workaround.

1. Define a custom Entity Materializer Source:

    public class MyEntityMaterializerSource : EntityMaterializerSource
        private static readonly MethodInfo NormalizeMethod = typeof(DateTimeMapper).GetTypeInfo().GetMethod(nameof(DateTimeMapper.Normalize));

        public override Expression CreateReadValueExpression(Expression valueBuffer, Type type, int index, IProperty property = null)
            if (type == typeof(DateTime))
                return Expression.Call(
                    base.CreateReadValueExpression(valueBuffer, type, index, property)

            return base.CreateReadValueExpression(valueBuffer, type, index, property);

2. Create a simple class to set kind of datetimes:

    public static class DateTimeMapper
        public static DateTime Normalize(DateTime value)
            return DateTime.SpecifyKind(value, DateTimeKind.Utc);

3. And finally replace  IEntityMaterializerSource by MyEntityMaterializerSource on DbContextOptionsBuilder:

DbContextOptions.ReplaceService<IEntityMaterializerSource, AbpEntityMaterializerSource>()

Then Entity Framework Core will use MyEntityMaterializerSource instead of default EntityMaterializerSource and MyEntityMaterializerSource will specify Kind of all DateTime’s to UTC.

Note: You probably want to handle nullable DateTime (DateTime?) properties too. In that case, remember to extend the code above to handle DateTime? too.

  • Mark
    Posted at 07:38, May 4, 2017

    Great workaround. As a side note, you can override OnConfiguring in the context class to replace IEntityMaterializerSource:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

  • Richard Beauchamp
    Posted at 21:21, October 2, 2017

    Thanks so much for this post. Exactly what I needed!

  • WiL
    Posted at 18:04, December 6, 2017

    EntityMaterializerSource Class

    Namespace: Microsoft.EntityFrameworkCore.Metadata.Internal
    Assembly: Microsoft.EntityFrameworkCore.dll

    This API supports the Entity Framework Core infrastructure and is not intended to be used directly from your code. This API may change or be removed in future releases.

  • hisuwh
    Posted at 17:39, May 1, 2018

    Thanks for the post.

    To me this seems much nicer than the ObjectMaterialized implementations

    • İsmail Çagdaş
      Posted at 17:46, May 1, 2018

      Thanks hisuwh :)

Post a Comment