Entity framework 4 如何在实体框架中获取实体的原始值?
在EF4.0中,如果我理解正确,实体中有两种类型的值:当前值和原始值。Entity framework 4 如何在实体框架中获取实体的原始值?,entity-framework-4,entity,Entity Framework 4,Entity,在EF4.0中,如果我理解正确,实体中有两种类型的值:当前值和原始值。 我们可以通过调用ApplyOriginalValues(TEntity)方法设置原始值,但如何获取原始值?您可以通过 @对于EF 5,Eranga答案已过时。出于某些原因,使用以下语句获取原始值时,EF 5无法正常工作: var originalValues=context.Entry(myEntity.originalValues); 我的工作解决方案使用DbSet中的AsNoTracking()方法,如下例所示: va
我们可以通过调用ApplyOriginalValues(TEntity)方法设置原始值,但如何获取原始值?您可以通过
@对于EF 5,Eranga答案已过时。出于某些原因,使用以下语句获取原始值时,EF 5无法正常工作:
var originalValues=context.Entry(myEntity.originalValues);
我的工作解决方案使用DbSet
中的AsNoTracking()
方法,如下例所示:
var originalEntity=context.MyEntities.AsNoTracking().FirstOrDefault(me=>me.MyEntityID==myEntity.MyEntityID);
这可以进一步细化为以下内容:
var originalEntity=context.MyEntities.AsNoTracking()
.FirstOrDefault(me=>me.MyEntityID==myEntity.MyEntityID);
在上面的
中,很好,不需要响应。我遇到了类似的问题,AsNoTracking不是我的选择,所以我想出了一个对我来说足够有效的方法:首先“克隆”实体,然后进行更改
public T Clone<T>(T entity)
where T : class, new() {
var clone = new T();
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
foreach (var property in properties) {
property.SetValue(clone, property.GetValue(entity));
}
return clone;
}
公共T克隆(T实体)
其中T:class,new(){
var clone=newt();
var properties=typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.flattHierarchy)
其中(a=>a.CanRead&&
a、 能写&&
a、 GetMethod.IsFinal);
foreach(属性中的var属性){
SetValue(克隆,property.GetValue(实体));
}
返回克隆;
}
然后将克隆与更改的克隆进行比较
public string GenerateChangeText<T>(T original, T current)
where T : class, new() {
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
var changes = string.Empty;
foreach (var property in properties) {
var originalValue = property.GetValue(original);
var currentValue = property.GetValue(current);
if (originalValue == null && currentValue == null) continue;
if ((originalValue != null && !originalValue.Equals(currentValue)) ||
(currentValue != null && !currentValue.Equals(originalValue))) {
changes += $" changed {property} from {original ?? "NULL"} to {current ?? "NULL"}.";
}
}
return changes;
}
公共字符串GenerateChangeText(T原始,T当前)
其中T:class,new(){
var properties=typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.flattHierarchy)
.其中(a=>a.CanRead&&
a、 能写&&
a、 GetMethod.IsFinal);
var changes=string.Empty;
foreach(属性中的var属性){
var originalValue=property.GetValue(原始);
var currentValue=property.GetValue(当前);
如果(originalValue==null&¤tValue==null)继续;
if((originalValue!=null&!originalValue.Equals(currentValue))||
(currentValue!=null&!currentValue.Equals(originalValue))){
changes+=$“将{property}从{original???“NULL”}更改为{current???“NULL”}。”;
}
}
回报变化;
}
有几个版本的Entity Framework正在使用中
我自己更喜欢先编写代码,有了这个API,就很容易了
_context.Entry(Entity).Reload();
文件
旧的API在ObjectContext上有一个刷新方法,它在某些用例中会有所帮助
ObjectContext.Refresh(RefreshMode.StoreWins, Entity);
文档这个答案指的是实体框架6。在EF 6中,有一个原始值和当前值,在查看并没有找到一个好的答案后,我提出了以下测试函数,并认为我会将其发布给其他需要这样做的人
private void test()
{
// table has a field Description of type varchar(200)
WDMDBEntities context = new WDMDBEntities();
var query = context.Brands;
List<Brand> records = query.ToList();
if (records.Count > 0)
{
Brand currentRecord = records[0];
currentRecord.Description = "some new text";
string originalValue = null;
switch (context.Entry(currentRecord).State)
{
case System.Data.Entity.EntityState.Added:
originalValue = null;
break;
case System.Data.Entity.EntityState.Deleted:
case System.Data.Entity.EntityState.Detached:
case System.Data.Entity.EntityState.Modified:
case System.Data.Entity.EntityState.Unchanged:
originalValue = context.Entry(currentRecord).Property(u => u.Description).OriginalValue;
break;
}
}
context.Dispose();
}
private void test()
{
//表具有varchar(200)类型的字段说明
WDMDBenties上下文=新的WDMDBenties();
var query=context.Brands;
列表记录=query.ToList();
如果(records.Count>0)
{
品牌currentRecord=记录[0];
currentRecord.Description=“一些新文本”;
字符串originalValue=null;
开关(context.Entry(currentRecord.State)
{
案例System.Data.Entity.EntityState.Add:
originalValue=null;
打破
案例System.Data.Entity.EntityState.Deleted:
案例System.Data.Entity.EntityState.Distached:
案例System.Data.Entity.EntityState.Modified:
案例System.Data.Entity.EntityState.Unchanged:
originalValue=context.Entry(currentRecord).Property(u=>u.Description).originalValue;
打破
}
}
context.Dispose();
}
对不起我的英语。
通过这种方式,您可以以对象实体的形式获取原始实体值,而无需更改编辑值
例如:
如果你想编辑一个人,上面的一行是这样的
var originalPerson = (Person)context.Entry(editPerson).OriginalValues.ToObject();
originalValues是DbDataRecord类型。如何将其转换为实体类型?@Sun它没有实体类型。您需要将值强制转换为适当的类型。例如var name=(字符串)原始值[“name”]代码>如何仅获取修改后的值???@AwaisMahmood我认为这值得一个单独的问题。@CiganoMorrisonMendez。。请访问此。。我问了这个问题,但没有得到答案。。请注意,AsNoTracking将从DB读取实体。它可能已被并发任务更改,在这种情况下,您可能会继续使用不正确的数据…@0xDEADBEEF。上下文不是线程安全的,对于这种情况,使用事务很重要,但这是另一个主题。
var originalEntity = (EntityType)context.Entry(editEntity).OriginalValues.ToObject();
var originalPerson = (Person)context.Entry(editPerson).OriginalValues.ToObject();