EF CORE 2.1 HasConversion对datetime类型的所有属性

时间:2018-06-06 19:06:51

标签: c# asp.net-core entity-framework-core

我之前使用DateTimeKindEntityMaterializerSource(Git)在读取实体时将所有DateTime转换为UTC,因为默认值未指定。

使用EF核心2.1,DateTimeKindEntityMaterializerSource不再有效但我们实际上可以这样做

         builder
        .Entity<ESDataQuotation>()
        .Property(e => e.CreatedDate)
        .HasConversion(v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc));

但是,我有许多DateTime的属性,我想如果有办法为DateTime类型的所有属性进行转换。

3 个答案:

答案 0 :(得分:22)

摘自EF Core 2.1 Value Conversions文档主题:

  

目前无法在一个地方指定给定类型的每个属性必须使用相同的值转换器。此功能将在未来版本中考虑。

在此之前,您可以使用OnModelCreating覆盖末尾的典型循环来发现所有实体类型和属性:

var dateTimeConverter = new ValueConverter<DateTime, DateTime>(
    v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc));

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    foreach (var property in entityType.GetProperties())
    {
        if (property.ClrType == typeof(DateTime) || property.ClrType == typeof(DateTime?))
            property.SetValueConverter(dateTimeConverter);
    }
}

答案 1 :(得分:4)

只是以为我可以投入两分钱

此处存在一个问题:https://github.com/aspnet/EntityFrameworkCore/issues/10784

Ivan的解决方案将适用于简单类型,例如std::aligned_storage等,但是在调用<plugin name="cordova-admob-sdk" spec="~0.13.1"> <variable name="PLAY_SERVICES_VERSION" value="11.6.0" /> </plugin>时使用用户定义类型时,它将崩溃。在上面的链接中的问题中对此进行了更好的描述。要使其与用户定义的类型一起使用,您将必须使用DateTime

对于通用解决方法,您可以使用以下扩展方法:

entityType.GetProperties()

答案 2 :(得分:0)

这不适用于评论部分,因此我添加了一个答案。这是我用来转换列表和字典的代码。

foreach (var entity in builder.Model.GetEntityTypes())
        {
            foreach (var property in entity.ClrType.GetProperties())
            {
                if (property.PropertyType == typeof(List<string>))
                {
                    builder.Entity(entity.Name).Property(property.Name).HasConversion(new ValueConverter<List<string>, string>(v => v.ToJson(), v => v.FromJson<List<string>>())).HasColumnType("json");
                }
                else if (property.PropertyType == typeof(Dictionary<string, string>))
                {
                    builder.Entity(entity.Name).Property(property.Name).HasConversion(new ValueConverter<Dictionary<string, string>, string>(v => v.ToJson(), v => v.FromJson<Dictionary<string, string>>())).HasColumnType("json");
                }
                else if (property.PropertyType == typeof(List<List<string>>))
                {
                    builder.Entity(entity.Name).Property(property.Name).HasConversion(new ValueConverter<List<List<string>>, string>(v => v.ToJson(), v => v.FromJson<List<List<string>>>())).HasColumnType("json");
                }
                else if (property.PropertyType == typeof(bool))
                {
                    builder.Entity(entity.Name).Property(property.Name).HasConversion(new BoolToZeroOneConverter<short>());
                }
            }
        }