2009-06-09 91 views
1

我在我的BaseController上有一個名爲DataContext的屬性,它包含我的LINQ to SQL數據上下文(或用於測試的假上下文)。當使用參數的構造函數(換句話說,當ASP.NET MVC的請求時),我的LINQ to SQL數據上下文的新實例被分配給屬性:爲什麼我的DataContext只有一個動作爲null?

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

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

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

也是我BaseController,我設置了一些全球ViewData項目:

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

這對幾乎所有的行爲都可以正常工作。不工作的只有一個是我的AccountController的退出動作:

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

這引發BaseController.OnActionExecuting在一個NullReferenceException。在執行該特定操作時,DataContext屬性爲空。

爲什麼這隻會發生在一個動作?

注: IDataContextWrapper和DataContextWrapper簡單地包裝了LINQ到SQL DataContext對象的現有功能,以便它可以與在單元測試中假上下文來代替。它不會自行進行任何處理,但會將其留給底層的DataContext,所以我非常確定這不是問題。

+0

只是爲了驗證,你沒有重複使用或持久化DataContext嗎? DataContext應該創建並在一個工作單元中過期。當我做錯了這件事時,我通過奇怪的行爲惹上了很大的麻煩。 – Serapth 2009-06-09 22:41:33

+0

我有一個DataContext的實例爲整個控制器只分配一次(當控制器被創建時),如果這就是你的意思。我可以在其他操作(在OnActionExecuting和操作方法本身中)中多次成功訪問它,但在註銷方法的情況下,DataContext僅使用一次(在OnActionExecuting中)。 – 2009-06-09 22:50:22

+0

好吧,這是不好的,如果這是你的問題的原因,不會讓我震驚。數據上下文不應該被持久化。在我的特殊情況下,問題表現爲不同的用戶看到對方的數據(真的......只是一個節目的一小部分)。我不能肯定地說這是你的問題,但我可以向你保證,這是有問題的。 – Serapth 2009-06-09 23:12:55

回答

0

由於我不太明白的原因,當爲註銷操作創建一個新的AccountController時,ASP.NET MVC正在使用帶有空參數的第二個構造函數(可能是一個bug?)。當參數爲空時,我改變類創建一個新的默認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在某些情況下使用了默認的構造函數,而在其他情況下使用了默認的構造函數。任何人都可以對此有所瞭解嗎?

1

跟進我的意見,check out this link更具體的鏈接Microsoft文檔here其狀態:

一般來說,一個DataContext實例設計壽命爲一個「工作單位」但是你的應用程序定義術語。 DataContext是輕量級的,創建起來並不昂貴。典型的LINQ to SQL應用程序在方法範圍創建DataContext實例,或者作爲表示相關數據庫操作的邏輯集合的短期類的成員。

微軟做了一個糟糕的工作,解釋了這一點,並坦率地解釋了首先在n層環境中使用Linq。在我的特殊情況下,我有一個(靜態)datacontext通過Singleton模式實現,我猜測你也是這樣做的。 (因爲它是最合理的設計,恕我直言)。然而,這並不是做事的方式。在我的情況下,修復其實很簡單,每次都改變我的GetDataContext()調用返回一個新的DataContext,而不是返回靜態實例。然而,你會發現,這會產生一大堆問題。一旦你發現它們,它們都不是無法克服的,但絕對是一種痛苦。

如果你有這樣的設置(你的DataContext的Singleton訪問器),修改它以查看它是否修復了你的問題。

無論如何,不​​要使用全局DataContext,也不要在處理n層體系結構時保留DataContext。

即使這不能解決您的特定問題,我強烈建議您重新構建您的解決方案,以使DataContext具有一個工作單位的生命週期,如果它還沒有咬你,它會。

相關問題