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

EntityFramework Core format DateTime in sqlite database

我正在将 EF Core 2.0 与 SQLite 结合使用,我想减小数据库的大小而不丢失 table 列中人类可读的日期时间值。目前,数据上下文将完整的 DateTime CLR 对象存储为一个字符串,如“2018-03-10 16:18:17.1013863”,但在我的例子中,“2018-03-10 16:18:17”就足够了。我必须做什么?

如果小数秒为零,则不会存储它们。您可以安全地将它们从现有数据中删除。更新您的应用程序以不指定它们。您可以急切地执行此操作(当您在实体上设置 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();
}

添加 bricelam 回复。一个更好(更短和更快)的微调毫秒代码是:

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

如果您真的想缩小尺寸,您可以向要缩小尺寸的每一列添加自定义转换,如下所示:

 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);
            }

或者您也可以将其应用于所有日期属性,请参见