2014-10-09 3 views
0

좋아요, 꽤 복잡한 게시물이므로 긴 게시물을 읽을 준비를하십시오.내 DbContext가 삭제되지 않는 이유 또는 예상대로 작동하지 않는 이유

저는 Microsoft Unity와 리포지토리 및 작업 단위 (UOW)의 사용자 지정 구현과 함께 Entity Framework를 사용하고 있습니다. 모든

첫째, 나는 저장소가 수행

public class Repository<TEntity> : RepositoryBase<TEntity>, 
             IRepository<TEntity> 
    where TEntity : class 
{ 
    #region Constructors 

    public Repository(IDbContext context, UnitOfWork unitOfWork) 
     : base(context, unitOfWork) 
    { } 

    #endregion 

    #region Properties 

    private bool _disposed; 

    #endregion 

    #region Methods 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       Context.Dispose(); // Dispose the main context. 
      } 
     } 

     _disposed = true; 
    } 

    #endregion 

    // Extra code has been removed for clarity. 
} 

을 나는 이것이 내가 저장소가 꽤 정직하고, 저장소가 IDbContext (사용자 인터페이스)에 따라 다르며는 IDisposable을 구현하지 추측 인터페이스, 기본 clsses에 정의 된, 여기에 구현 해요.

개체를 삭제할 때 문맥에서 Dispose()를 호출합니다. 이는 충분히 생각해야합니다. 이 클래스 I 컨텍스트를 처분 할 파기하는 방법에있어서, IDispose 인터페이스 또한 IDbContext 소요되며 포함 저장소로서

/// <summary> 
///  Provides methods that respond to actions executed in a <see cref="IUnitOfWork"/>. 
/// </summary> 
public class UnitOfWork : IUnitOfWork 
{ 
    #region Constructors 

    /// <summary> 
    ///  Initializes a new instance of the <see cref="IUnitOfWork"/> with a given <see cref="IDbContext"/>. 
    /// </summary> 
    /// <param name="context">The <see cref="IDbContext"/> in which the entities are available.</param> 
    public UnitOfWork(IDbContext context) 
    { 
     _context = context; 
    } 

    #endregion 

    #region Properties 

    /// <summary> 
    ///  The <see cref="IDbContext"/> in which the entities are available. 
    /// </summary> 
    protected readonly IDbContext _context; 

    /// <summary> 
    ///  Provides a way to identify if the <see cref="UnitOfWork"/> has been disposed. 
    /// </summary> 
    private bool _disposed; 

    #endregion 

    #region IUnitOfWork Members 

    // Extra code removed for clarity. 

    public virtual void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       _context.Dispose(); // Dispose the main context. 
      } 
     } 

     _disposed = true; 
    } 

    #endregion 
} 

:

다음에, I는 UnitOfWork에가 있는가.

그런 다음 위의 것과 상속 된 또 다른 UnitOfWork가 있습니다.

public class UnitOfWork : Repository.UnitOfWork 
{ 
    #region Constructors 

    public UnitOfWork(IDbContext context) 
     : base(context) 
    { 
     _pageRepository = new Repository<Page>(context, this); 
    } 

    #endregion 

    #region Properties 

    private readonly IRepository<Page> _pageRepository; 

    public IRepository<Page> PageRepository { get { return _pageRepository; } } 

    private bool _disposed; 

    #endregion 

    #region Methods 

    public override void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 

     base.Dispose(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       // Disposes all the repositories. 
       PageRepository.Dispose(); 

       // Disposes the main context. 
       _context.Dispose(); 
      } 
     } 

     _disposed = true; 
    } 

    #endregion 
} 

그래서, 여기에 내가 컨텍스트를 처분하고 나는 그 후, 나는 전화, 여기에 PageRepository을 배치하고있어 다른의 UnitOfWork에서 Dispose 메서드를 오버라이드 (override) : 내가 내 저장소를 정의하는 작업 단위에서의 문맥을 처리해야하는 base.Dispose() 메소드.

public class OxygenDataContext : DbContext, IDbContext 
{ 
    #region Constructors 

    public OxygenDataContext() : 
     base("Ox") 
    { } 

    #endregion 

    #region Properties 

    public IDbSet<Page> Page { get; set; } 

    #endregion 

    #region IDbContext Members 

    public IRepositoryEntityCollection<TEntity> Set<TEntity>() where TEntity : class 
    { return new RepositoryEntityCollection<TEntity>(this); } 

    public new void SaveChanges() 
    { base.SaveChanges(); } 

    #endregion 
} 

그래서, 기본적으로이 이미는 IDisposable 인터페이스를 구현 않습니다

내 IDbContext 구현은 DbContext (엔티티 프레임 워크 구현)입니다. 이제

, 나는 유니티 자신의 구체적인 유형의 인터페이스를 해결하는 데 :

container.RegisterType<IDbContext, OxygenDataContext>(new PerRequestLifetimeManager()); 
container.RegisterType<IUnitOfWork, UnitOfWork>(new PerRequestLifetimeManager()); 

그리고 Global.asax 파일에서, 나는 (내가 명시 적으로 때문에 그렇지 않으면이 코드를 필요로하는 EndRequest 이벤트에서 개체를 처분 내가 지금 페이지를 열고 일하고있어 데이터베이스에서 콘텐츠를 검색 할 때 나는 SQL을 사용하여 직접 데이터베이스에 데이터를 변경할 때, 그러나,

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    var container = DependencyResolver.Current.GetService<IUnityContainer>(); 

    container.Resolve<IDbContext>().Dispose(); 
    container.Resolve<IUnitOfWork>().Dispose(); 
} 

을하지만 :) 폐기가 호출되지 않는 것 같다 서버 관리 탐색기를 열고 페이지를 새로 고치십시오. 페이지는 여전히 오래된 데이터를 표시하지만 모든 것이 올바르게 폐기되었다고 생각합니다.

누구나 아이디어가 있습니다.

편집

그것은 문맥이 배치되고있는 것 같아,하지만 난 VirtualFileProvider를 사용하고 있는데 그 반환 값에 업데이트되지 않습니다.

가 ExecuteReader는 개방 가능한 연결이 필요합니다 응용 프로그램이 시작되고 나는 (버튼을 길게) CTRL-F5를 눌러있을 때

또한

는 다음 다양한 오류는 그들 중 하나가되고, 팝업됩니다. 연결의 현재 상태가 열려 있습니다.

Entity Framework에서 예상되는 동작입니까?

답변

1

좋아, 문제를 발견했습니다.

MVC 용 VirtualFileProvider에서 문제가 발생했습니다. 저장소를 폐기하지 않고 작업 단위를 통해 리포지토리를 사용하고있었습니다.

데이터를 수정하여 데이터베이스에 연결하기 위해 Using 문을 사용하여 데이터를 검색했습니다. 지금 모든 문제가 해결되었습니다.

관련 문제