C# 如何刷新DbContext

C# 如何刷新DbContext,c#,entity-framework,entity-framework-4,refresh,dbcontext,C#,Entity Framework,Entity Framework 4,Refresh,Dbcontext,我想在不重新创建的情况下刷新我的DbContext的所有实体,我尝试了以下操作,但没有一个有意义: var context = ((IObjectContextAdapter)myDbContext).ObjectContext; var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries( EntitySt

我想在不重新创建的情况下刷新我的
DbContext
的所有实体,我尝试了以下操作,但没有一个有意义:

var context = ((IObjectContextAdapter)myDbContext).ObjectContext;

var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
                                   EntityState.Added
                                   | EntityState.Deleted
                                   | EntityState.Modified
                                   | EntityState.Unchanged)
                          where entry.EntityKey != null
                          select entry.Entity);

context.Refresh(RefreshMode.StoreWins, refreshableObjects);
//.......................................................................
foreach (var entry in this.Orm.ChangeTracker.Entries())
{
    entry.State = EntityState.Unchanged;
}
this.Orm.ChangeTracker.DetectChanges();
并且是唯一一个刷新我的
DbContext

foreach (var i in this.Orm.ChangeTracker.Entries())
    i.Reload();

但是太慢了。你能帮我选择正确的方法吗?

我检查了这个,id工作正常:

//Search
Box box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45);

//breakpoint here, change Name of Box by sql management studio

//Refresh
var context = ((IObjectContextAdapter)dbContext).ObjectContext;
context.Refresh(System.Data.Entity.Core.Objects.RefreshMode.StoreWins, box);

//Check refresh and if it is in context
box = dbContext.Boxes.FirstOrDefault(x => x.BoxId == 45);

你确定它是同一个db上下文吗?

我刚刚发现应该计算
可枚举的
结果,因为
Refresh
方法将其作为对象获取,而不计算它

var context = ((IObjectContextAdapter)myDbContext).ObjectContext;
var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
                                           EntityState.Added
                                           | EntityState.Deleted
                                           | EntityState.Modified
                                           | EntityState.Unchanged)
                          where entry.EntityKey != null
                          select entry.Entity).ToList();

context.Refresh(RefreshMode.StoreWins, refreshableObjects);
我更喜欢以下内容:

var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c=>c.Entity).ToList();
context.Refresh(RefreshMode.StoreWins, refreshableObjects);
使用System.Data.Entity.Core.Objects;
使用System.Data.Entity.Infrastructure;
使用System.Linq;
命名空间System.Data.Entity
{
公共静态类DbContextensions
{
/// 
///刷新非分离实体
/// 
///实体的背景
///商店或客户获胜
///当指定时,仅刷新该类型的实体。当为null时,修改所有未分离的实体
/// 
公共静态DbContext RefreshEntites(此DbContext DbContext,RefreshMode RefreshMode,类型entityType)
{
//https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/
var objectContext=((IObjectContextAdapter)dbContext).objectContext;
var refreshableObjects=objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged)
.Where(x=>entityType==null | | x.Entity.GetType()==entityType)
.Where(entry=>entry.EntityKey!=null)
.选择(e=>e.Entity)
.ToArray();
Refresh(RefreshMode.StoreWins,refreshableObjects);
返回dbContext;
}
公共静态DbContext RefreshAllEntites(此DbContext DbContext,RefreshMode RefreshMode)
{
返回RefreshEntites(dbContext:dbContext,refreshMode:refreshMode,entityType:null);//null entityType是通配符
}
公共静态DbContext RefreshEntites(此DbContext DbContext,RefreshMode RefreshMode)
{
返回RefreshEntites(dbContext:dbContext,refreshMode:refreshMode,entityType:typeof(TEntity));
}
}
}

在某些情况下,如果某个集合已由第三方应用程序更新,则在刷新该集合的对象时可能不会重新加载该集合

我有一个例子,我有一个对象A,它和一个对象B有一对多的关系

应用程序1加载A.ListB为空的对象A。 应用程序2填充A.ListB集合。 应用程序1重新加载对象A

使用上面的解决方案,A.ListB保持为空。我必须显式地重新加载集合A.ListB

以下是重新加载所有集合的一般方法:

var context = ((IObjectContextAdapter)this).ObjectContext;

// detach all added entities
ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList().ForEach(e => e.State = EntityState.Detached);

// select entities
var refreshableObjects = ChangeTracker.Entries().Select(e => e.Entity).ToList();

// refresh each refreshable object
foreach (var @object in refreshableObjects)
{
    // refresh each collection of the object
    context.ObjectStateManager.GetRelationshipManager(@object).GetAllRelatedEnds().Where( r => r.IsLoaded).ToList().ForEach( c => c.Load() );

    // refresh the object
    context.Refresh(RefreshMode.StoreWins, @object);
}

在数据库中插入之后,我有一个触发器,我在一个事务中工作,所以我需要在相同的上下文中获取触发器生成的新值。这对我很有用:

using (var ctx = new context())
{
    ctx.Connection.Open();
    ctx.Transaction = ctx.Connection.BeginTransaction();

    ctx.Entities.InsertOnSubmit(itemDB);
    ctx.SubmitChanges();
    ctx.Refresh(RefreshMode.OverwriteCurrentValues, itemDB);

    Model newModel = itemDB.ToModel();

    ctx.Transaction.Commit();
    return newModel;
}
catch (Exception ex)
{
    ctx.Transaction.Rollback();
}


您是否尝试过context.Refresh(RefreshMode,Entity)并在调试器和sql监视器中查看它是否真的更新了?@yonexbat:我手动更改了sql中的数据,并调用了
context.Refresh(RefreshMode,Entity)
但没有更新任何更改,并使用
I.Reload()完成了相同的场景以及在my
DbContext
中更新的所有更改。很抱歉将其作为答案添加,但我不知道如何在注释中设置文本格式。注意:谢谢,我使用它来刷新单个实体,但是我需要刷新我的
DbContext
的所有实体,而不仅仅是单个
实体
实体集合
或某个实体的相关实体
。好的。我将重新创建DbContext。myDbContext=新建myDbContext();:好吧,但正如我上面提到的,我不想这样做。这看起来很完美。太糟糕了,我在.Net Core中,它不存在。使用您的方法,我得到:要刷新的对象集合中索引0处的元素处于添加状态。无法刷新处于此状态的对象。@isti\u spl:u最好在referesh
if(entry.state==EntityState.Added)entry.state=EntityState.Detached;//你拯救了我的一天莫森:我得到了与@isti_spl相同的结果,但我不清楚解决方案是什么。我们如何处理添加的状态?@YeahStu您根本无法从上面的代码中删除EntityState。从正在添加的存储中刷新实体是没有意义的。商店里还没有。
using (var ctx = new context())
{
    ctx.Connection.Open();
    ctx.Transaction = ctx.Connection.BeginTransaction();

    ctx.Entities.InsertOnSubmit(itemDB);
    ctx.SubmitChanges();
    ctx.Refresh(RefreshMode.OverwriteCurrentValues, itemDB);

    Model newModel = itemDB.ToModel();

    ctx.Transaction.Commit();
    return newModel;
}
catch (Exception ex)
{
    ctx.Transaction.Rollback();
}