我开始创建这样的模型:
public abstract class EditableBase
{
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public int CreatedBy { get; set; }
public int ModifiedBy { get; set; }
}
public class Project : EditableBase
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
}
我在应用程序启动时使用此行:
Database.SetInitializer<ModelContext>(
new DropCreateDatabaseIfModelChanges<ModelContext>());
创建了一个名为Projects的表,其中上面提到的所有属性都是列......这正是我想要的。
但是,现在我需要在DbContext上发出SaveChanges()时填充一些默认值。当我保存时,我需要使用适当的值更新ModifiedOn和ModifiedBy属性。
通常我至少会在数据库端(触发器或存储过程)执行DateTime值,但是这显然不是一个选项,因为数据库将在类更改时被删除。因为我先做了代码,所以我没有模型设计师可以调整属性。
我想要做的是在EditableBase类中添加一个方法,该方法在执行SaveChanges()时被调用,从而将所有逻辑都保存在一个地方。是否有可能做到这一点?实现目标的最佳方式是什么?
答案 0 :(得分:8)
在您的派生SaveChanges
中覆盖DbContext
:
public override int SaveChanges()
{
foreach(var entry in ChangeTracker.Entries<EditableBase>())
{
var entity = entry.Entity;
if (entry.State == EntityState.Added)
{
entity.CreatedOn = ...;
entity.CreatedBy = ...;
}
else if (entry.State == EntityState.Modified)
{
entity.ModifiedOn = ...;
entity.ModifiedBy = ...;
}
}
return base.SaveChanges();
}
我只是不确定通用Entries
是否可以直接使用您的基类型,因为它实际上并未映射为基本实体。还有非泛型版本,因此您可以将其重写为更复杂的linq查询或在循环中测试每个条目的实体类型。
答案 1 :(得分:0)
好吧,您可以完全控制实体的代码。我想你可能想要实现类似IPropertyChanged的模式来更新你的属性。
答案 2 :(得分:0)
考虑this post中你在setter(或构造函数)上做某事的两个选项?
默认属性解决方案似乎很好。