7

일반적인 문제 인 것처럼 보였습니다 : 데이터베이스의 값을 업데이트하고 있지만 EF가 개체의 원래 메모리 내 복사본을 사용하고 있으며 변경된 값이 표시된 데이터에 반영되지 않았습니다. 왜 그런지 이해하지만 주위를 둘러 볼 방법이없는 것 같습니다.EF 4.1 RC의 DbContext 수준에서 변경 내용 추적을 해제하려면 어떻게합니까?

가장 일반적인 해결책은 변경 추적을 완전히 끄거나 (쿼리 할 때 AsNoTracking() 확장 메서드 사용) 개체에 액세스 할 때마다 새로 고침을 강제 실행하도록 설정하는 것 같습니다. 이는 내 용도에 적합합니다. 내가 이렇게 내 저장소의 All() 방법을 변경하는 경우

public class Db : DbContext 
{ 
    private IDbSet<Product> _products; 

    public IDbSet<Product> Products 
    { 
     get { return _products ?? (_products = DbSet<Product>()); } 
    } 

    public virtual IDbSet<T> DbSet<T>() where T : class 
    { 
     return Set<T>(); 
    } 

    public virtual void Commit() 
    { 
     base.SaveChanges(); 
    } 
} 

:

public abstract class RepositoryBase<T> where T : class 
{ 
    private readonly IDbSet<T> _dbset; 
    private readonly IUnitOfWork _unitOfWork; 

    protected RepositoryBase(IUnitOfWork unitOfWork) 
    { 
     _unitOfWork = unitOfWork; 
     _dbset = _unitOfWork.Database.Set<T>(); 
    } 

    public virtual IQueryable<T> All() 
    { 
     return _dbset; 
    } 

    // Some other IQueryable methods here (Query, GetByProductCode etc) 

    public virtual T Get(long id) 
    { 
     return _dbset.Find(id); 
    } 
}  

그리고 이런 DbContext :

나는 내 다른 저장소로부터 상속 일반적인 기본 저장소를 가지고 :

public virtual IQueryable<T> All() 
{ 
    return _dbset.AsNoTracking(); 
} 

나는 원하는 결과를 얻습니다. - 제품을 표시하는 페이지가 새로 고쳐질 때 데이터베이스의 갱신 사항이 반영됩니다. 그러나 Get() 메서드에서는이 확장 메서드가 IQueryable에서만 작동하므로이 작업을 수행 할 수 없습니다.

변경 추적을 절대로 필요로하지 않기 때문에 이상적으로 이것을 DbContext 레벨로 설정하고 싶습니다. 그러나이를 수행하는 분명한 방법이없는 것 같습니다. 주제에 관한 문서는 거의 없습니다. (누군가 나를 가르쳐 줄 수 없다면? 제발!).

내가 사용할 구성 옵션과 함께 DbContext에 생성자를 추가하는 시도 :

public Db() 
{ 
    base.Configuration.ProxyCreationEnabled = false; 
    base.Configuration.AutoDetectChangesEnabled = false; 
} 

을하지만 난 단지 그들이 정말로 무엇으로 추측하고있어 인정해야한다 (나는 단지 소스보고를 통해 발견 코드), 어쨌든 어떤 영향도 미치지 않는 것 같습니다.

도움을 주시면 감사하겠습니다. 더 많은 정보/코드가 도움이 될 경우 알려 주시기 바랍니다.

답변

6

Find 메서드를 사용하고 싶지 않을 때마다 새로운 데이터를 가져 오도록 컨텍스트를 강제 설정하려는 경우. Find 메서드는 항상 내부 저장소를 먼저 쿼리합니다. 대신 다음을 사용하십시오.

public virtual T Get(long id) 
{ 
    return All().SingleOrDefault(e => e.Id == id); 
} 

하지만이 부분이 무엇인지 이해하지 못합니까? 제품 을 표시하는 페이지가

상황에 맞는 작업의 단위를 새로 고칠 때

데이터베이스의 업데이트가 반영됩니다 : 당신은 무엇을 의미합니까. 작업 단위로 사용해야합니다. 웹 응용 프로그램 또는 웹 서비스에서 요청 당 새로운 컨텍스트 인스턴스를 만드는 것을 의미합니다. winforms/wpf 응용 프로그램에서는 논리 블록 당 컨텍스트 (프레젠터 등)를 사용하는 것을 의미합니다. 따라서 매우 특정한 시나리오에서만이 기능이 필요하지만 전 세계적으로 사용하기를 원합니다. completely bad solution 인 요청 사이에서 컨텍스트를 재사용하고있는 것으로 보입니다. 각 요청에 대한 컨텍스트를 다시 작성하는 데 성능 비용은 없습니다.

+0

답변 해 주셔서 감사합니다. 나는 * 요청 *마다 새로운 컨텍스트를 만들 수 있다고 생각했지만, 여기에서 지적한 바에 따르면, Ninject 구성에서 잘못된 설정이있을 수 있다고 생각합니다 ... 내일 확인하고 다시보고 할 것입니다! –

+0

이것이 문제인 것처럼 보입니다. 요청에 대해 새로운 DbContext를 생성하지 않고 있습니다. 또는 주입에 InRequestScope()을 지정 했더라도 Ninject가 아닙니다. 나는 이것이 이제는 별개의 질문이라고 생각하지만, 지금까지이 문제에 대한 귀하의 도움에 감사드립니다. –

+0

해결책을 찾았 기 때문에이 질문에 직접 답하지는 않았지만이 대답을 수락했습니다. –

관련 문제