views:

552

answers:

5

In a web application that I have run across, I found the following code to deal with the DataContext when dealing with LinqToSQL

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"];
      }
    }
  }

Then referencing it later doing this:

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

I have been looking into best practices when dealing with LinqToSQL.

I am unsure about the approach this one has taken when dealing with DataContext not being ThreadSafe and keeping a static copy of it around.

Is this a good approach to take in a web application?

@Longhorn213 - Based on what you said and the more I have read into HttpContext because of that, I think you are right. But in the application that I have inherited it is confusing this because at the beginning of each method they are requerying the db to get the information, then modifying that instance of the datacontext and submitting changes on it.

From this, I think this method should be discouraged because it is giving the false impression that the datacontext is static and persisting between requests. If a future developer thinks that requerying the data at the beginning of a method because they think it is already there, they could run into problems and not understand why.

So I guess my question is, should this method be discouraged in future development?

A: 

A DataContext is cheap to make and you won't gain much by caching it in this way.

Andrew Hare
+4  A: 

This is not a static copy. Note that the property retrieves it from Context.Items, which is per-request. This is a per-request copy of the DataContext, accessed through a static property.

On the other hand, this property is assuming only a single thread per request, which may not be true forever.

John Saunders
A: 

I have done many Linq to Sql web apps and I am not sure if what you have would work.

The datacontext is supposed to track the changes you make to your objects and it will not do that in this instance.

So when you go hit submit changes, it will not know that any of your objects where updated, thus not update the database.

You have to do some extra work with the datacontext in a disconnected environment like a web application. It is hardest with an update, but not really that bad. I would not cache and just recreate it.

David Basarab
Why would it not know about changes made during the request?
John Saunders
Because the datacontext is only accessed on request and is destroyed after the post back cycle. You go back to the server and the datacontext isn't there to keep track of the changes made to any of the objects.
David Basarab
I said, "during the request".
John Saunders
A: 

Also the context itself is not transactional so it is theoretically possible an update could occur on another request and your update could fail.

yieldvs
A: 

I prefer to create a Page base class (inherit from System.Web.UI.Page), and expose a DataContext property. It ensures that there is one instance of DataContext per page request.

This has worked well for me, it's a good balance IMHO. You can just call DataContext.SubmitChanges() at the end of the page and be assured that everything is updated. You also ensure that all the changes are for one user at a time.

Doing this via static will cause pain -- I fear DataContext will lose track of changes since it's trying to track changes for many users concurrently. I don't think it was designed for that.

Matt Sherman
The code he posted is not a static DataContext. It is per-request. Only a single request and therefore only a single user can access it.
John Saunders
yeah, agreed. it's "hidden" behind a static method.
Matt Sherman