实体框架刷新上下文?


100

我怎样才能刷新自己的背景?我有基于数据库视图的实体,当我对一个表进行更新时,该实体具有视图的导航属性,该实体是更新的,但视图不会刷新以符合新的更新...只是想从中获取新信息Db数据。谢谢!

Answers:


91

刷新上下文中的实体的最佳方法是处理上下文并创建一个新的上下文。

如果您确实需要刷新某些实体,并且您在DbContext类中使用Code First方法,则可以使用

    public static void ReloadEntity<TEntity>(
        this DbContext context, 
        TEntity entity)
        where TEntity : class
    {
        context.Entry(entity).Reload();
    }

要重新加载集合导航属性,可以使用

    public static void ReloadNavigationProperty<TEntity, TElement>(
        this DbContext context, 
        TEntity entity, 
        Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
        where TEntity : class
        where TElement : class
    {
        context.Entry(entity).Collection<TElement>(navigationProperty).Query();
    }

参考:https : //msdn.microsoft.com/zh-cn/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx# M: System.Data.Entity.Infrastructure.DbEntityEntry重新加载


3
我无法使它重新加载子导航属性。
保罗

@David,context.ReloadNavigationProperty(parent, p => p.Children);如果有的话可以使用class Parent { ICollection<Child> Children; }
Jinjinov

在EF Core中,您可以使用Query()。Load(),例如context.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
Rubenisme

我不明白为什么这种解决方案获得了如此高的投票。context.Entry(entity).Collection <TElement>(navigationProperty).Query()不会重新加载子集合。它只为您提供一个Iqueryable,代表用于获取集合的查询。它实际上什么也没做。
Statler

72
yourContext.Entry(yourEntity).Reload();

3
感谢您的简单解决方案。我认为没有必要像RX_DID_RX这样的扩展方法将其封装起来
Thomas

这对我来说是个救星。谢谢!
凯文

19
请注意,这不会重新加载集合导航属性,仅重新加载实体条目本身。
詹姆斯·威尔金斯

28

如果要重新加载特定实体,则使用DbContextApi,RX_DID_RX已经为您提供了答案。

如果要重新加载/刷新所有已加载的实体,请执行以下操作:

如果您使用的是Entity Framework 4.1+(可能是EF5或EF 6),则DbContext API:

public void RefreshAll()
{
     foreach (var entity in ctx.ChangeTracker.Entries())
     {
           entity.Reload();
     }
}

如果您使用的是EntityFramework 4(ObjectContext API):

public void RefreshAll()
{
     // Get all objects in statemanager with entityKey
     // (context.Refresh will throw an exception otherwise)
     var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted
                                               | EntityState.Modified
                                               | EntityState.Unchanged)
                                      where entry.EntityKey != null
                                      select entry.Entity);

     context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}

无论如何,最好的建议是,尝试使用“短期环境”,这样可以避免此类问题。

关于此事,我写了几篇文章:

https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/


好一个!!拯救了我的一天!
Radu D

15

使用刷新方法:

context.Refresh(RefreshMode.StoreWins, yourEntity);

或者替代地,处理您当前的上下文并创建一个新的上下文。


@JMK在这里到底什么不起作用?它对我来说似乎很好(EF 6.1.1)。
塞巴斯蒂安·克莱斯曼斯基

@SebastianKrysmanski我大约一年前发表评论,也许自那以后已经解决了?
JMK

5
我认为它仅适用于objectcontext,而不适用于dbcontext。他们之间需要对话
batmaci

3
@batmaci可以轻松实现((IObjectContextAdapter)dbContext).ObjectContext
Daniel Z.

3
并没有这么说不完整。
user441521 16/09/26


1

EF 6

在我的方案中,实体框架未获取新更新的数据。原因可能是数据已超出其范围进行了更新。提取后刷新数据解决了我的问题。

private void RefreshData(DBEntity entity)
{
    if (entity == null) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entity);
}

private void RefreshData(List<DBEntity> entities)
{
    if (entities == null || entities.Count == 0) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entities);
}

1
我使用EF6。为什么这比一个更好_context.Entry(entity).Reload();
卡萨巴·托斯

据我所记得,.Reload()在EF6中不可用。@CsabaToth
Mahbubur Ra​​hman

0

由于性能下降,不建议使用Reload刷新db上下文。在执行每个操作之前初始化dbcontext的新实例已足够好,并且是最佳实践。它还为您提供了每个操作的最新上下文。

using (YourContext ctx = new YourContext())
{
   //Your operations
}

6
杜德(Dude)..每次转储您的上下文也将刷新您不希望被刷新的内容,这实际上会导致性能问题。
LuckyLikey

2
这是一个可怕的想法,因为它影响编写单元测试的能力。如果您的代码关闭并在新的上下文中发出消息,那么在单元测试期间它将如何工作?
胜利者

5
如果您显示一些示例而不是提出批评,这对我和其他人将很有用。
aog

对于小型网站来说很好。
alikuli

-7

我已经让自己的头受伤了!答案很简单-我只是回到基础知识...

some_Entities   e2 = new some_Entities(); //your entity.

更新/删除后,请在下面添加此行-您正在重新加载实体-没有幻想的系统方法。

e2 = new some_Entities(); //reset.

2
这将“工作” -这只是一个可怕的想法,将有其他后果
亚当嘿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.