C# 如何从ChangeTracker获取原始实体
是否有办法从C# 如何从ChangeTracker获取原始实体,c#,.net,entity-framework,entity-framework-6,C#,.net,Entity Framework,Entity Framework 6,是否有办法从ChangeTracker获取原始实体本身(而不仅仅是原始值) 如果状态是修改的,那么我想我可以这样做: // Get the DbEntityEntry from the DbContext.ChangeTracker... // Store the current values var currentValues = entry.CurrentValues.Clone(); // Set to the original values entry.CurrentValues.S
ChangeTracker
获取原始实体本身(而不仅仅是原始值)
如果状态
是修改的
,那么我想我可以这样做:
// 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<Foo>())
{
if (entry.State == System.Data.EntityState.Modified)
{
// use entry.OriginalValues
Foo originalFoo = CreateWithValues<Foo>(entry.OriginalValues);
}
}
我建议在具体化时克隆实体,并将它们附加到第二个上下文中,以保持整个原始对象的图形(当然,如果您需要的话)。您可以通过修改T4模板使它们都可克隆。很好。下面是一个稍加修改的版本,它将处理复杂的属性:
public static TEntity GetOriginal<TEntity>(this DbContext ctx, TEntity updatedEntity) where TEntity : class
{
Func<DbPropertyValues, Type, object> 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));
}
publicstatictenty-GetOriginal(这个DbContext-ctx,tenty-updatedEntity),其中TEntity:class
{
Func getOriginal=null;
getOriginal=(原始值,类型)=>
{
object original=Activator.CreateInstance(类型,true);
foreach(原始值中的var ptyName.PropertyName)
{
var property=type.GetProperty(ptyName);
对象值=原始值[ptyName];
if(值为DbPropertyValues)//嵌套的复杂对象
{
SetValue(original,getOriginal(值为DbPropertyValues,property.PropertyType));
}
其他的
{
property.SetValue(原始,值);
}
}
归还原件;
};
return(tenty)getOriginal(ctx.Entry(updatedEntity).originalvalue,typeof(tenty));
}
在使用EF 6时,我使用以下代码从代理类型获取底层POCO实体类型
var entityType = ObjectContext.GetObjectType(dbEntitymodifiedEntry.Entity.GetType());
ObjectContext.GetObjectType
:从代理对象返回POCO我可能缺少一个细节,但我相信我知道如何做到这一点(这只是获取原始值,对吗?)我需要原始实体的实际强类型表示,而不仅仅是原始值。@Eric您想要具有原始属性值的实体对象吗?是的,这是正确的。也许是一种在给定一组原始值的情况下构造实体的方法…@Eric done,我编写了一个方法,该方法通过ReflectionTanks@Clement创建实体并设置属性值。我遇到了这个问题,花了很多时间来获取旧的。首先,我尝试返回完全断开连接的对象。但它在更新时也有自己的问题。这一个有效,需要测试更多的场景thoughHey@Clement。这一个不具有导航属性。有什么线索吗?不确定,我还没有测试过导航属性。因为它使用的是Activator.CreateInstance,所以我不希望延迟加载导航属性(因为它依赖于EF生成的运行时代理类型)。您可以更改此代码来处理它们…谢谢@Clement。我一次加载一个图表,但没有修改以一般方式填充导航属性。这只返回一个类型。我无法获得原始值。
var entityType = ObjectContext.GetObjectType(dbEntitymodifiedEntry.Entity.GetType());