如何从ChangeTracker获取原始实体

有没有办法从ChangeTracker (而不仅仅是原始值)获取原始实体本身?

如果StateModified ,那么我想我可以这样做:

 // Get the DbEntityEntry from the DbContext.ChangeTracker... // Store the current values var currentValues = entry.CurrentValues.Clone(); // Set to the original values entry.CurrentValues.SetValues(entry.OriginalValues.Clone()); // Now we have the original entity Foo entity = (Foo)entry.Entity; // Do something with it... // Restore the current values entry.CurrentValues.SetValues(currentValues); 

但这似乎并不是很好,我确信它有问题,我不知道……有更好的方法吗?

我正在使用Entity Framework 6。

覆盖DbContext的SaveChanges或只是从上下文访问ChangeTracker

 foreach (var entry in context.ChangeTracker.Entries()) { if (entry.State == System.Data.EntityState.Modified) { // use entry.OriginalValues Foo originalFoo = CreateWithValues(entry.OriginalValues); } } 

这是一个创建具有原始值的新实体的方法。 因此,所有实体都应该有一个无参数的公共构造函数,您只需使用new构造一个实例:

 private T CreateWithValues(DbPropertyValues values) where T : new() { T entity = new T(); Type type = typeof(T); foreach (var name in values.PropertyNames) { var property = type.GetProperty(name); property.SetValue(entity, values.GetValue(name)); } return entity; } 

尼斯。 这是一个稍微修改过的版本,它将处理复杂的属性:

 public static TEntity GetOriginal(this DbContext ctx, TEntity updatedEntity) where TEntity : class { Func getOriginal = null; getOriginal = (originalValues, type) => { object original = Activator.CreateInstance(type, true); foreach (var ptyName in originalValues.PropertyNames) { var property = type.GetProperty(ptyName); object value = originalValues[ptyName]; if (value is DbPropertyValues) //nested complex object { property.SetValue(original, getOriginal(value as DbPropertyValues, property.PropertyType)); } else { property.SetValue(original, value); } } return original; }; return (TEntity)getOriginal(ctx.Entry(updatedEntity).OriginalValues, typeof(TEntity)); } 

我建议在物化上克隆实体并将它们附加到第二个上下文以保持整个原始对象图(当然如果你需要它)。 您可以通过修改T4模板使它们全部成为ICloneable。

在使用EF 6时,我使用以下代码从代理类型中获取基础POCO实体类型,

 var entityType = ObjectContext.GetObjectType(dbEntitymodifiedEntry.Entity.GetType()); 

ObjectContext.GetObjectType :从代理对象返回POCO