EntityFramework核心格式在sqlite数据库中的DateTime

时间:2018-03-13 16:45:11

标签: c# database datetime entity-framework-core ef-core-2.0

我正在使用带有SQLite的EF Core 2.0,我希望减少数据库的大小而不会丢失表格列中人类可读的日期时间值。目前,数据上下文将完整的DateTime CLR对象存储为类似于" 2018-03-10 16:18:17.1013863"但在我的情况下" 2018-03-10 16:18:17"会是的。我该怎么办?

3 个答案:

答案 0 :(得分:1)

如果小数秒为零,则不会存储小数秒。您可以安全地从现有数据中删除它们。更新您的应用程序以不指定它们。您可以在DateTime期间热切地(在实体上设置SaveChanges值)或懒惰时执行此操作。

public override int SaveChanges()
{
    var dateTimeProperties =
        from e in ChangeTracker.Entries()
        where e.State == EntityState.Added
                || e.State == EntityState.Modified
        from p in e.Properties
        where p.CurrentValue is DateTime
        select p;
    foreach (var property in dateTimeProperties)
    {
        // Strip millisecond
        var value = (DateTime)property.CurrentValue;
        property.CurrentValue = new DateTime(
            value.Year,
            value.Month,
            value.Day,
            value.Hour,
            value.Minute,
            value.Second);
    }

    return base.SaveChanges();
}

答案 1 :(得分:1)

添加bricelam答复。修剪毫秒的更好(更短,更快)的代码是:

property.CurrentValue = value.AddTicks(-value.Ticks % TimeSpan.TicksPerSecond)

答案 2 :(得分:0)

如果您确实想剃除更大的尺寸,可以向要减小尺寸的每一列添加自定义转换,如下所示:

 protected override void OnModelCreating(ModelBuilder constructor) =>
 constructor.Entity<YourEntity>().Property(c => c.DatePropertyOfYourEntity)
                    .HasConversion(f => f.ATextoYYMMDD(), s => s.AFechaYYMMDD());

我使用以下扩展方法在日期和字符串格式YYMMDD之间进行非常快速的转换:

    public static string ATextoYYMMDD(this DateTime fechaHora) {

        var chars = new char[6];
        var valor = fechaHora.Year % 100;
        chars[0] = (char)(valor / 10 + '0');
        chars[1] = (char)(valor % 10 + '0');
        valor = fechaHora.Month;
        chars[2] = (char)(valor / 10 + '0');
        chars[3] = (char)(valor % 10 + '0');
        valor = fechaHora.Day;
        chars[4] = (char)(valor / 10 + '0');
        chars[5] = (char)(valor % 10 + '0');
        return new string(chars);

    } 

    public static DateTime AFechaYYMMDD(this string s)
        => new DateTime((s[0] - '0') * 10 + s[1] - '0' + 2000, 
        (s[2] - '0') * 10 + s[3] - '0', (s[4] - '0') * 10 + s[5] - '0');

如果您想将其应用于实现接口的多个实体,则可以执行以下操作:

            var convertidor = new ValueConverter<DateTime, string>
                (f => f.ATextoYYMMDD(), s => s.AFechaYYMMDD());    
            foreach (var tipoEntidad in constructor.Model
                .GetEntityTypes().Where(t => typeof(IYourInterface).IsAssignableFrom(t.ClrType.BaseType))) {

                constructor.Entity(tipoEntidad.Name)
                    .Property("YourPropertyName").HasConversion(convertidor);
            }

或者您也可以将其应用于所有日期属性,请参见EF CORE 2.1 HasConversion on all properties of type datetime