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);
}
或者您也可以将其应用于所有日期属性,请参见
我正在将 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);
}
或者您也可以将其应用于所有日期属性,请参见