2009-06-09 3 views
1

내 LINQ to SQL 데이터 컨텍스트 (또는 테스트 용 가짜 컨텍스트)를 보유하는 DataContext라는 BaseController의 속성이 있습니다. (ASP.NET MVC에 대한 요청이 즉,) 매개 변수없는 생성자를 사용하는 경우 SQL 데이터 컨텍스트 내 LINQ의 새로운 인스턴스가 속성에 할당됩니다 :왜 내 DataContext는 하나의 작업에서만 null입니까?

내 BaseController에서 또한
public class BaseController : Controller { 
    public IDataContextWrapper DataContext { get; set; } 

    public BaseController() : this(new DataContextWrapper<MyDataContext>()) { } 

    public BaseController(IDataContextWrapper context) { 
     DataContext = context; 
    } 
} 

, 일부 글로벌 ViewData 항목을 설정했습니다.

protected override void OnActionExecuting(ActionExecutingContext filterContext) { 
    ViewData["Example"] = DataContext.Table<Example>().Count(); 
    base.OnActionExecuting(filterContext); 
} 

거의 모든 작업에서 정상적으로 작동합니다. 이 BaseController.OnActionExecuting 동안 NullReferenceException이 제기

public ActionResult Logout() { 
    FormsAuth.SignOut(); 
    return RedirectToResult("Login"); 
} 

: 작동하지 않는 유일한 사람이 내 AccountController의 로그 아웃 작업입니다. 특정 작업을 실행할 때 DataContext 속성은 null입니다.

왜 한 번의 작업에서만 발생합니까?

참고 : IDataContextWrapper 및 DataContextWrapper는 단위 테스트에서 가짜 컨텍스트로 바꿀 수 있도록 LINQ의 기존 기능을 SQL DataContext 개체로 간단하게 래핑합니다. 그것은 독자적으로 처분하지 않지만, 기본 DataContext까지 남겨 둡니다, 그래서 저는 그것이 문제가 아니라는 것을 확신합니다.

+0

확인하기 만하면 DataContext를 재사용하거나 지속하지 않습니다. DataContext는 작업 단위 내에서 작성되고 만료되어야합니다. 나는 이것을 잘못했을 때 이상한 행동으로 엉덩이를 무겁게 가볍게 잡았다. – Serapth

+0

한 번만 (컨트롤러가 생성 될 때) 할당 된 전체 컨트롤러에 대해 하나의 DataContext 인스턴스가 있습니다. OnActionExecuting과 액션 메서드 자체에서 여러 번 성공적으로 액세스 할 수 있지만 Logout 메서드의 경우 DataContext는 OnActionExecuting에서 한 번만 사용됩니다. –

+0

좋아, 이건 나쁘지 않아서 그게 너의 문제의 원인이라면 나에게 충격을주지 않을거야. 데이터 컨텍스트는 지속되지 않아야합니다. 필자의 경우, 문제는 서로 다른 사용자가 서로의 데이터를 보는 것처럼 보였습니다 (실제로 ... 쇼 스토퍼가 조금씩). 나는 이것이 당신의 문제인지 말할 수는 없지만, 나는 당신에게 약속 할 수있다. 그것은 문제가있다. – Serapth

답변

0

내가 이해하지 못하는 이유 때문에 Logout 액션을 위해 새 AccountController가 생성되면 ASP.NET MVC는 null 매개 변수 (버그 일 수 있음)와 함께 두 번째 생성자를 사용하고 있습니다.매개 변수가 null 일 때 클래스를 새 기본 DataContext를 만들도록 변경했습니다.

public class BaseController : Controller { 
    public IDataContextWrapper DataContext { get; set; } 

    public BaseController() : this(null) { } 

    public BaseController(IDataContextWrapper context) { 
     DataContext = dataContext ?? new DataContextWrapper<MyDataContext>(); 
    } 
} 

이제는 작동합니다.

ASP.NET MVC가 기본 생성자를 사용하는 경우와 다른 경우 과부하가 발생하는 것은 이상한 일입니다. 누구든지 이것에 대해 밝힐 수 있습니까?

+0

DI 프레임 워크 및/또는'SetControllerFactory'를 사용하여 global.asax에 등록 된 컨트롤러 팩토리에서 달리 언급하지 않는 한 MVC는 항상 기본 매개 변수없는 생성자를 사용해야합니다. –

1

내 댓글, check out this link보다 구체적으로 링크 상태 Microsoft 설명서 here 후속하려면 일반적으로

가하는 DataContext의 인스턴스가 하나의 "작업 단위"지속하도록 설계되어 있지만 응용 프로그램이 있다고 정의 기간. DataContext는 가볍고 만들 비용도 들지 않습니다. 일반적인 LINQ to SQL 응용 프로그램은 메서드 범위에서 또는 관련 데이터베이스 작업의 논리적 집합을 나타내는 수명이 짧은 클래스의 멤버로 DataContext 인스턴스를 만듭니다.

마이크로 소프트는 이것을 설명하고 솔직히 n 계층 환경에서 Linq를 사용하여 솔직하게 설명했습니다. 필자의 경우에는 Singleton 패턴을 통해 구현 된 하나의 (정적 인) datacontext가 있었는데, 나는 당신이 한 일을 추측하고있다. (가장 논리적 인 설계이므로 IMHO). 그러나 이것은 일을하는 방법이 아닙니다. 필자의 경우, 고정 인스턴스를 반환하는 대신 매번 GetDataContext() 호출을 변경하여 매번 새 DataContext를 반환하도록 수정하는 것이 실제로 매우 쉽습니다. 이것은 그러나, 당신은 발견 할 것이다, 완전히 새로운 작물을 창조한다. 일단 당신이 그들을 알아 내면 그들 중 어느 누구도 극복 할 수 없지만, 분명히 고통입니다.

그런 설정 (DataContext에 대한 싱글 톤 접근 자)이 있으면 문제를 수정하는지 확인하십시오.

상관없이 전역 DataContext를 사용하지 말고 n 계층 아키텍처를 처리하는 경우 DataContext를 유지하지 마십시오.

이 방법으로도 문제가 해결되지 않더라도 솔루션을 다시 설계하여 DataContexts에 작업 단위가 적용되도록하는 것이 좋습니다. 그렇지 않으면 문제가 해결됩니다.

+0

내 시스템은 CodePlex의 Nerd Dinner 샘플과 동일한 방식으로 작동합니다. 컨트롤러가 생성 될 때마다 새로운 DataContext를 얻습니다. 정적 싱글 톤이 아닙니다 (내 코드에서 볼 수 있듯이). 내가 액세스하기 전에 DataContext가 삭제되는 경우 NullReferenceException 대신 ObjectDisposedException을 수신하지 않습니까? NullReferenceException은 DataContext 속성이 처음부터 초기화되지 않는다고 생각하게 만듭니다. 이는 불가능한 것처럼 보입니다. –

관련 문제