10

我首先创建了一些这样的模型:

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() 时被调用,从而将所有涉及的逻辑保存在一个地方。是否有可能做到这一点?实现我的目标的最佳方式是什么?

4

3 回答 3

9

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 查询或在循环中测试每个条目的实体类型。

于 2011-03-31T16:42:37.963 回答
0

是否考虑过这篇文章中的两个选项,您在设置器(或构造器)上做某事?

默认属性解决方案似乎是一个不错的解决方案。

于 2011-05-14T13:49:50.127 回答
0

好吧,您可以完全控制实体的代码。我想您可能想要实现类似 IPropertyChanged 的​​模式来更新您的属性。

于 2011-03-31T13:23:06.887 回答