我的应用程序使用EF6 数据库优先方法。数据库中的所有实体都有2个常用属性“CreatedDateTime”和“ModifiedDateTime”。
目前当我执行SaveChanges()时,我会根据我是创建新实体还是更新现有实体来明确设置这两个属性。
如果是新实体,则设置其他属性,否则只设置ModifiedDateTime属性。
我想知道是否有办法在保存或更新操作中隐式设置这两个属性?
更新1
我知道我必须覆盖Savechanges()方法,但是真正的问题是SaveChanges需要访问这两个属性。所以我这里只看到两个选项:
1 GT;使用反射来查找实体是否具有这些属性并进行设置
2 - ;修改默认的T4生成,以便它使用预定义的接口派生所有实体。此接口将具有这两个属性。 SaveChanges()方法可以检查实体是否派生自此接口并设置属性。
我绝对不想使用反射使用选项1.
在DB first方法之前,有没有其他方法或有人这样做过?
答案 0 :(得分:4)
采用第二种方法:调整T4文件以包含对界面的引用(例如IChangeTrack
):
public interface IChangeTrack
{
/// <summary>
/// When has this entry be created
/// </summary>
[Required]
DateTime CreatedDateTime { get; set; }
/// <summary>
/// When has this entry been modified
/// </summary>
DateTime? ModifiedDateTime { get; set; }
}
现在通过执行以下操作覆盖SaveChanges()
例程:
/// <summary>
/// Enhance save changes to handle system fields.
/// </summary>
/// <returns></returns>
public override int SaveChanges()
{
HandleChanges();
int changes = base.SaveChanges();
return changes;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
HandleChanges();
int changes = await base.SaveChangesAsync(cancellationToken);
return changes;
}
private void HandleChanges()
{
ChangeTracker.DetectChanges();
var entries = ChangeTracker.Entries<IChangeTrack>();
if (entries != null)
{
foreach (DbEntityEntry<IChangeTrack> entry in entries)
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedDateTime = DateTime.UtcNow
break;
case EntityState.Modified:
entry.Entity.ModifiedDateTime = DateTime.UtcNow;
break;
}
}
}
}