从DbContext获取所有跟踪的实体?

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

我的所有模型对象都inheritance自AbstractModel类以允许这种行为。 这个类看起来像这样:

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

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

要使用它,我需要能够获得DbContext正在跟踪的所有实体的列表,并且如果对象被标记为AddedModified则在它们上调用UpdateDates()

我似乎无法访问DbContext存储此信息的任何地方。 我可以使用dbContext.Entry(object).State来获取单个实体的EntityState ,但是我无法弄清楚如何获取所有被跟踪实体的列表。

我该怎么做呢?

我想你可以使用ChangeTracker :

 public class MyContext : DbContext { //... public override int SaveChanges() { foreach (var dbEntityEntry in ChangeTracker.Entries()) { dbEntityEntry.Entity.UpdateDates(); } return base.SaveChanges(); } } 

这里接受的解决方案对于EF4以上比ObjectContext建议更好 – 我们遇到了问题,例如我们在测试上下文中使用的内存db与上述解决方案不兼容(在inheritance方案中获得某些已修改条目的Detached状态) 。 此解决方案使用DbContext本机方式检索跟踪的实体:

 context.ChangeTracker.Entries() .Where (t => t.State == EntityState.Modified) 

这在我们的项目中运行良好,因此每次添加具有标准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 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; } } } } 

reflection调用不是问题:对于具有25个属性(很多)的对象,一百万次reflection查询需要平均〜210 ms。