Entity Framework 새로 고침 컨텍스트?


100

컨텍스트를 새로 고치려면 어떻게해야합니까? 내 데이터베이스의 뷰를 기반으로하는 엔터티가 있고 뷰에 대한 탐색 속성이있는 하나의 테이블 엔터티를 업데이트 할 때 엔터티가 업데이트되지만 뷰가 새 업데이트에 따라 새로 고쳐지지 않습니다. Db 데이터. 감사!

답변:


91

컨텍스트에서 항목을 새로 고치는 가장 좋은 방법은 컨텍스트를 삭제하고 새 항목을 만드는 것입니다.

당신이 경우 정말 일부 개체를 새로 고쳐야하고 DbContext 클래스와 코드 첫 번째 접근 방식을 사용하고, 당신은 사용할 수 있습니다

    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/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M:System.Data.Entity.Infrastructure.DbEntityEntry .Reload


3
자식 탐색 속성을 다시로드하기 위해이 작업을 수행 할 수 없습니다.
Paul

당신이 사용할 수있는 @ 데이비드 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

이것은 나를위한 생명의 은인이었습니다. 감사합니다!
Kevin

19
이것은 컬렉션 탐색 속성을 다시로드하지 않고 엔터티 항목 자체 만 다시로드합니다.
James Wilkins

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).
Sebastian Krysmanski

@SebastianKrysmanski 내가 거의 1 년 전에 댓글을 달았는데, 그 이후로 수정 되었을까요?
JMK

5
나는 그것이 objectcontext에서만 작동하고 dbcontext에서는 작동하지 않는다고 생각합니다. 그들 사이의 대화가 필요합니다
batmaci

3
@batmaci 어느 쉽게 수행 할 수 있습니다((IObjectContextAdapter)dbContext).ObjectContext
다니엘 Z.

3
그렇게 약간 불완전하다고 언급되지 않았습니다.
user441521

6

context.Reload ()는 MVC 4, EF 5에서 나를 위해 작동하지 않았으므로 이것을했습니다.

context.Entry(entity).State = EntityState.Detached;
entity = context.Find(entity.ID);

잘 작동합니다.


1

EF 6

내 시나리오에서 Entity Framework는 새로 업데이트 된 데이터를 선택하지 않았습니다. 그 이유는 데이터가 범위 밖에서 업데이트 되었기 때문일 수 있습니다. 가져온 후 데이터를 새로 고침하여 문제가 해결되었습니다.

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에 있습니다. 이것이 a보다 나은 이유는 무엇 _context.Entry(entity).Reload();입니까?
Csaba Toth

내가 기억할 .Reload()수있는 한 EF6에서는 사용할 수 없습니다. @CsabaToth
Mahbubur Rahman

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
그 것이다 "작품"- 그냥 끔찍한 생각과 다른 결과를 초래할 것입니다
아담 헤이
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.