我正在尝试使用实体框架来完成一种“通用”机制来更新我的 SQL Server 数据库中的时间数据。
我所做的是创建一个名为“标记”的接口ITemporalData
,它定义了两个需要存在的属性 -DateTime ValidFrom
和DateTime? ValidTo
.
public interface ITemporalData
{
DateTime ValidFrom { get; set; }
DateTime? ValidTo { get; set; }
}
我希望在我的DbContext.SaveChanges()
覆盖中实现一种“通用”方法:
- 克隆任何
ITemporalData
对象,这会给我一个新对象来存储(EntityState.Added
),并将其ValidFrom
值设置为当前日期和时间 - 将原始的、修改后的条目重置为其数据库值(调用
.Reset()
实体),然后ValidTo
将该“旧”记录的设置为当前日期和时间
虽然我可以像这样轻松地过滤掉覆盖ITemporalData
中的修改对象:SaveChanges()
public partial class MyDbContext
{
// override the "SaveChanges" method
public override int SaveChanges()
{
DateTime currentDateTime = DateTime.Now;
// get the modified entities that implement the ITemporalData interface
IEnumerable<DbEntityEntry<ITemporalData>> temporalEntities = ChangeTracker.Entries<ITemporalData>().Where(e => e.State == EntityState.Modified);
foreach (var temporalEntity in temporalEntities)
{
// how would I do that, really? I only have an interface - can't clone an interface......
var cloned = temporalEntity.Entity.Clone();
// and once it's cloned, I would need to add the new record to the correct DbSet<T> to store it
// set the "old" records "ValidTo" property to the current date&time
temporalEntity.Entity.ValidTo = currentDateTime;
}
return base.SaveChanges();
}
}
我正在为“克隆修改后的记录”方法而苦苦挣扎——我只有一个ITemporalData
接口,真的——但是克隆(使用 AutoMapper 或其他方法)总是取决于实际的、底层的具体数据类型.....