2009-06-09 40 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具有一个工作单位的生命周期,如果它还没有咬你,它会。

相关问题