在实体的modelBUilder中,我尝试通过自定义生成器在添加和更新时设置创建和修改的日期。选择此路径的原因是因为创建模型的DbContext被用作基类。此基类由SQL Server和SQLite EFCore扩展继承。因此,在上下文中应该有数据库显式功能。GetDateUTC()和最初实现的SQL Server触发器。
modelBuilder.Entity<CommunicationSendRequest>(entity =>
{
...
entity.Property(p => p.CreatedAt).ValueGeneratedOnAdd().HasValueGenerator<CreatedAtTimeGenerator>();
entity.Property(p => p.ModifiedAt).ValueGeneratedOnUpdate().HasValueGenerator<ModifiedAtTimeGenerator>();
});
但是添加和更新时发生的情况总是将这两个属性设置为新值。意思是在全新插入上设置了Modifyat,在更新上设置了createdat。这将删除在日期创建的真实值。
问题是那些价值生成器的设置正确吗?有没有一种方法可以使用生成器来完成此任务?在生成器中,我还尝试检查状态,仅在添加或修改状态后才返回值。但是国家总是等于独立。
public class CreatedAtTimeGenerator : ValueGenerator<DateTimeOffset>
{
public override DateTimeOffset Next(EntityEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
return DateTimeOffset.UtcNow;
}
public override bool GeneratesTemporaryValues { get; }
}
public class ModifiedAtTimeGenerator : ValueGenerator<DateTimeOffset>
{
public override DateTimeOffset Next(EntityEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
return DateTimeOffset.UtcNow;
}
public override bool GeneratesTemporaryValues { get; }
}
我实际上所做的是将ValueGenerate概念放在一起,处理它,创建CreatedAt,ModifiedAt,并在通过覆盖SaveChanges()方法创建此帖子的DeletedAt日期后添加它。
public override int SaveChanges()
{
var selectedEntityList = ChangeTracker.Entries()
.Where(x => (x.Entity is IEntityCreatedAt ||
x.Entity is IEntityModifiedAt ||
x.Entity is IEntityIsDeleted) &&
(x.State == EntityState.Added || x.State == EntityState.Modified)).ToList();
selectedEntityList.ForEach(entity =>
{
if (entity.State == EntityState.Added)
{
if (entity.Entity is IEntityCreatedAt)
((IEntityCreatedAt)entity.Entity).CreatedAt = DateTimeOffset.UtcNow;
}
if (entity.State == EntityState.Modified)
{
if (entity.Entity is IEntityModifiedAt)
((IEntityModifiedAt)entity.Entity).ModifiedAt = DateTimeOffset.UtcNow;
if (entity.Entity is IEntityIsDeleted)
if (((IEntityIsDeleted)entity.Entity).IsDeleted)
((IEntityIsDeleted)entity.Entity).DeletedAt = DateTimeOffset.UtcNow;
}
});
return base.SaveChanges();
}