EF Core 3 具有价值生成器
EF Core 3 Has Value Generator
在实体的 modelBUilder 中,我尝试通过自定义生成器在添加和更新时设置创建和修改日期。走这条路的原因是因为创建模型的 DbContext 正在使用基础 class。此基础 class 由 SQL 服务器和 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>();
});
但是在添加和更新两个属性时发生的事情总是设置为新值。意思是在全新的插入中设置了修改时间,在更新时设置了创建时间。这删除了 true 创建日期。
问题是那些值生成器设置正确吗?有没有办法使用生成器来完成此操作?在生成器中,我还尝试检查状态 return 只有当状态被添加或修改时的值。但是状态总是等于Detached。
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,并在 post 通过覆盖 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();
}
在实体的 modelBUilder 中,我尝试通过自定义生成器在添加和更新时设置创建和修改日期。走这条路的原因是因为创建模型的 DbContext 正在使用基础 class。此基础 class 由 SQL 服务器和 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>();
});
但是在添加和更新两个属性时发生的事情总是设置为新值。意思是在全新的插入中设置了修改时间,在更新时设置了创建时间。这删除了 true 创建日期。
问题是那些值生成器设置正确吗?有没有办法使用生成器来完成此操作?在生成器中,我还尝试检查状态 return 只有当状态被添加或修改时的值。但是状态总是等于Detached。
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,并在 post 通过覆盖 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();
}