一个Web应用程序中的LinqToSql静态DataContext

8
在我接触到的一个Web应用程序中,我发现以下代码用于在处理LinqToSQL时处理DataContext。
public partial class DbDataContext
  {
    public static DbDataContext DB
    {
      get
      {
        if (HttpContext.Current.Items["DB"] == null)
          HttpContext.Current.Items["DB"] = new DbDataContext();
        return (DbDataContext)HttpContext.Current.Items["DB"];
      }
    }
  }

然后稍后这样引用它:

DbDataContext.DB.Accounts.Single(a => a.accountId == accountId).guid = newGuid;
DbDataContext.DB.SubmitChanges();

我一直在研究处理LinqToSQL的最佳实践。

当涉及到DataContext不是线程安全的并且需要保留静态副本时,我对这种方法感到不确定。

在Web应用程序中采用这种方法是否可行?

@Longhorn213 - 根据您所说和我因此而更深入地了解HttpContext,我认为您是正确的。但是,在我继承的应用程序中,每个方法的开头都会重新查询数据库以获取信息,然后修改该数据上下文的实例并提交更改。

基于此,我认为应该避免使用这种方法,因为它会给人一种错误的印象,即数据上下文是静态的,并在请求之间持久存在。如果未来的开发人员认为在方法开始时重新查询数据是因为他们认为数据已经存在,那么他们可能会遇到问题,而不理解原因。

所以,我的问题是,未来的开发中是否应该避免使用这种方法?


这是一篇更详细的文章,链接在这里:http://blog.stevensanderson.com/2007/11/29/linq-to-sql-the-multi-tier-story/ - Jarrod Dixon
我们今晚刚刚推出了这个概念的一个变体。 - Jarrod Dixon
5个回答

6

这不是一个静态副本。请注意,该属性从Context.Items中检索它,该对象是每个请求的。这是DataContext的每个请求副本,通过静态属性访问。

另一方面,该属性假定每个请求仅使用单个线程,但这可能不总是正确的。


0
一个DataContext很容易创建,通过缓存它不会获得太多好处。

0

我已经做了很多Linq to Sql的Web应用程序,但我不确定你的方法是否可行。

数据上下文(DataContext)应该跟踪您对对象所做的更改,在这种情况下它将无法实现。

因此,当您提交更改时,它将不知道任何对象是否已更新,从而不会更新数据库。

在像Web应用程序这样的断开连接的环境中,您需要对数据上下文(DataContext)进行一些额外的工作。虽然更新最难,但并不是真的很糟糕。我建议不要缓存,只需重新创建即可。


2
为什么它不知道请求期间所做的更改? - John Saunders
因为数据上下文仅在请求时访问,并在回发周期后被销毁。当您返回服务器时,数据上下文不再存在,无法跟踪对任何对象所做的更改。 - David Basarab
1
我说,“在请求期间”。 - John Saunders

0

此外,上下文本身并不是事务性的,因此理论上可能会在另一个请求上发生更新,导致您的更新失败。


0
我更喜欢创建一个基于页面的类(继承自System.Web.UI.Page),并公开一个DataContext属性。这可以确保每个页面请求都有一个DataContext实例。
对我而言,这个方法已经奏效并且是一个很好的平衡点。你只需要在页面末尾调用DataContext.SubmitChanges()就能确保所有内容都被更新了。同时还可确保所有的更改只针对一个用户。
如果使用静态方式实现将会带来麻烦——因为DataContext试图同时跟踪多个用户的更改,所以可能会失去更改的轨迹。我认为它不是为此设计的。

1
他发布的代码不是静态DataContext,而是每个请求都有一个。只有一个请求,因此只有一个用户可以访问它。 - John Saunders
是的,同意。它被放置在一个静态方法背后,所以有点“隐藏”。 - Matt Sherman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接