Abh*_*eet 3 c# entity-framework entity-framework-core ef-core-2.1
期待构建一个框架(没有直接使用DbSets的存储库模式)自动填充Created并最后自动修改,而不是通过代码库吐出这些代码.
你能指出我正确的方向如何实现它.
在过去,我尝试在构造函数中填充这些,但是这看起来像是一个讨厌的代码,每次我们从数据库中调出来时,更改跟踪会将实体标记为已修改.
.ctor()
{
Created = DateTime.Now;
LastModified = DateTime.Now;
}
public interface IHasCreationLastModified
{
DateTime Created { get; set; }
DateTime? LastModified { get; set; }
}
public class Account : IEntity, IHasCreationLastModified
{
public long Id { get; set; }
public DateTime Created { get; set; }
public DateTime? LastModified { get; set; }
public virtual IdentityUser IdentityUser { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Iva*_*oev 15
从v2.1开始,EF Core提供状态更改事件:
New
Tracked和StateChanged事件onChangeTracker可用于编写对进入DbContext或改变其状态的实体作出反应的逻辑.
您可以从DbContext构造函数中订阅这些事件
ChangeTracker.Tracked += OnEntityTracked;
ChangeTracker.StateChanged += OnEntityStateChanged;
Run Code Online (Sandbox Code Playgroud)
并做这样的事情:
void OnEntityTracked(object sender, EntityTrackedEventArgs e)
{
if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IHasCreationLastModified entity)
entity.Created = DateTime.Now;
}
void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
entity.LastModified = DateTime.Now;
}
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案(我们当前在我工作的地方使用的解决方案)是重写SaveChanges()DbContext 中的方法并添加一点代码来循环更改实体设置值
public override int SaveChanges()
{
var changedEntriesCopy = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added ||
e.State == EntityState.Modified ||
e.State == EntityState.Deleted)
.ToList();
var saveTime = DateTime.Now;
foreach (var entityEntry in changedEntriesCopy)
{
if (entityEntry.Metadata.FindProperty("Created") != null && entityEntry.Property("Created").CurrentValue == null)
{
entityEntry.Property("Created").CurrentValue = saveTime;
}
if (entityEntry.Metadata.FindProperty("Updated") != null)
{
entityEntry.Property("Updated").CurrentValue = saveTime;
}
}
return base.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
我们的情况基本上设置类似于 - Created 在我们的情况下是可以为空的,因此当创建一个新实体时,在创建之前的代码中的值为 null(可以轻松检查 Created 是否已填充)。
可能还有其他解决方案,但这是我们最容易设置的解决方案,并且没有任何明显的性能影响
| 归档时间: |
|
| 查看次数: |
1100 次 |
| 最近记录: |