entity-framework - EF Core 3 具有价值生成器
问题描述
在实体的 modelBUilder 中,我尝试通过自定义生成器在添加和更新时设置创建和修改日期。走这条路的原因是因为创建模型的 DbContext 被用作基类。此基类由 SQL Server 和 SQLite EFCore 扩展继承。因此,上下文中应该有数据库显式功能。最初实现 SQL Server 的 GetDateUTC() 和触发器。
modelBuilder.Entity<CommunicationSendRequest>(entity =>
{
...
entity.Property(p => p.CreatedAt).ValueGeneratedOnAdd().HasValueGenerator<CreatedAtTimeGenerator>();
entity.Property(p => p.ModifiedAt).ValueGeneratedOnUpdate().HasValueGenerator<ModifiedAtTimeGenerator>();
});
但是在添加和更新两个属性时发生的事情总是设置为新值。对全新插入的含义设置了 modifiedat,在更新时设置了 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 的概念,并通过覆盖 SaveChanges() 方法来处理 CreatedAt、ModifiedAt 的创建,并在创建这篇文章后添加 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();
}
推荐阅读
- latex - Latex 多行多列表
- r - 如何将沿线的简单特征点转换为带端点的线段
- python - 将复杂列表隐藏到平面列表
- c# - 更新 ASP.net 服务器中的类后,所有用户的会话在浏览器中重置
- python - TensorFlow 无法将字符串类型的张量复制到设备
- sql - 如何从同一个表中选择不同的 2 个相同的列
- python - “ImportError:导入 pydot 失败。您必须安装 pydot 和 graphviz 才能使 `pydotprint` 工作。” 但是两者都安装了
- c - 如何将值传递给结构的指针成员
- c# - 通过从 appsettings.json 读取文件路径来创建文件会自动将我的项目的根目录添加到路径中
- android - RecyclerView 适配器中的错误 - 错误膨胀图像视图类