【问题标题】:Get all tracked entities from a DbContext?从 DbContext 获取所有跟踪的实体?
【发布时间】:2012-04-24 17:35:59
【问题描述】:

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

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

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

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

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

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

我该怎么做?

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    我认为您可以为此使用ChangeTracker

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

    【讨论】:

    • 感谢您的回答 - 我没有注意到 ChangeTracker 不知何故!
    【解决方案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 毫秒。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-13
        • 2018-09-27
        • 1970-01-01
        • 2020-09-27
        • 1970-01-01
        相关资源
        最近更新 更多