19

我数据库中的许多表都需要有一个“DateCreated”和“DateModified”列。我想在SaveChanges()调用时更新这些列。

我所有的模型对象都继承自一个类AbstractModel以允许这种行为。该类如下所示:

public abstract class AbstractModel {
    public virtual void UpdateDates() { }
}

然后,我计划在具有他们需要维护的字段的UpdateDates()任何子类中进行覆盖。DateCreatedDateModified

要使用它,我需要能够获取DbContext正在跟踪的所有实体的列表,并UpdateDates()在对象被标记为 isAdded或时调用它们Modified

我似乎无法访问DbContext存储此信息的任何位置。我可以dbContext.Entry(object).State获取EntityState单个实体的,但我不知道如何获取所有跟踪实体的列表。

我该怎么做呢?

4

3 回答 3

31

我认为您可以为此使用ChangeTracker

public class MyContext : DbContext
{
    //...

    public override int SaveChanges()
    {
        foreach (var dbEntityEntry in ChangeTracker.Entries<AbstractModel>())
        {
            dbEntityEntry.Entity.UpdateDates();
        }
        return base.SaveChanges();

    }
}
于 2012-04-12T11:28:08.780 回答
9

这里接受的解决方案对于上述 EF4 比 ObjectContext 建议更好 - 我们遇到了问题,例如我们在测试上下文中使用的内存数据库不能很好地与上述解决方案配合使用(在继承场景中为一些修改的条目获取分离状态) . 此解决方案使用 DbContext 本机方式来检索跟踪的实体:

context.ChangeTracker.Entries()
        .Where (t => t.State == EntityState.Modified)
于 2016-05-30T09:46:55.820 回答
2

这在我们的项目中运行良好,因此我们不必记住每次添加具有标准 LastUpdatedDateTime 属性的新实体时都覆盖某些内容。使用 EF4;对于 EF5 DbContext,我认为 ((IObjectContextAdapter)_dbContext).ObjectContext.ObjectStateManager 将为您提供对象状态管理器:

// In our SaveChanges wrapper:
        var entries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted);

        private static void PopulateDate(IEnumerable<ObjectStateEntry> entries)
                {
                    foreach (var entry in entries)
                    {
                        if (entry.State != EntityState.Deleted)
                        {
                            if ((entry.Entity != null) && (entry.Entity.GetType().GetProperty("LastUpdatedDateTime") != null))
                            {
                                ((dynamic)entry.Entity).LastUpdatedDateTime = DateTime.UtcNow;
                            }
                        }
                    }
                }

反射调用不是问题:对于具有 25 个属性(很多)的对象,一百万个反射查询平均需要约 210 毫秒。

于 2012-12-06T20:54:34.400 回答