Best practice and effective way of using DataContext in Linq to SQL?

NOTE: See my follow up post here for more info.

At work, Jeff and I have been throwing around ideas to find a best way to implement DataContext in Linq so that we can integrate it into the base class in our framework while achieving following goals.

  • Implementation should be easy and non-redundant, so that we do not need to do new DataContext(), every time we have to use one.
  • Portability of the DataContext should be such that we do not need to pass it around as parameters from one tier to another.
  • "Unit of work" pattern should be well represented and "very" transparent.
  • Context should not be persisted without intent, or be open to manipulation from other methods, such that "unit of work" is compromised or a transaction is ill-represented

These seem like simple goals given the features and flexibility of LINQ, however, in reality this has become much more difficult and annoying to achieve than we previously thought. Here are several ideas we have been kicking around, and problem it presents. I would like to hear from people who have effectively used LINQ Datacontext in these scenarios or in a pattern that's most effective.

 

1. Creating and disposing LINQ as required.

DbDataContext myContext = new DbDataContext();

//your code goes here

myContext.SubmitChanges();

Problems with this pattern:

  • Creating datacontext everytime we need to use is cumbersome and in my opinion just verbose.
  • If you have to use datacontext in any of the method this code calls, you'll have to pass the datacontext with it. This is one- too many parameters to pass around

     

2. Creating a static DataContext and using it throughout the application.

DataLayer.DataContext.Current

Problems with this pattern:

  • Creating static object isn't always a good thing. In this case, the context is available for manipulation at any level. And unit of work quickly becomes very hard to maintain
  • If manipulated by other threads or methods context isn't clean anymore and cannot be trusted

3. Ambient DataContext (Currently using this)

The idea behind ambient datacontext is that context is created for a particular thread or a httpcontext(in asp.net) as soon as there is a first call for the DataContext. Then the same context is used for that thread or request unless it is disposed manually. This is done by storing the context in the request/thread data store. The approach to this pattern is similar to static DataContext, however, separation is provided for each thread and requests. This works really well in Asp.Net, however, is again plagued by some of the problems of static context.

Problems with this pattern:

  • The context is available for manipulation at any level. And quickly becomes very hard to maintain unit of work
  • Portability across thread is very hard
  • Unit of work pattern is not transparent enough

4.  Finally, the last idea we've been trying to come up with is concept similar to TransactionScope.

In this pattern, you would used using{ } block to initialize your context and represent a "Datacontext Scope". Any method below that will automatically be able to figure out the proper context, through thread/request datastore. Then just before the dispose happens, you manually call the SubmitChanges() method. This is the one I like so far, however, has few practical problems.

Problems with this pattern:

  • If sub method needs to implement a new context, we need to figure out how to exclude it from the parent context's using block. If allowing multiple contexts in multiple using blocks, how do you determine which context to use in sub-sub methods?

 

Please do comment on what you think is the best approach to solving this problem.

Print | posted on Tuesday, March 18, 2008 8:51 PM

Feedback

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Nick Parker at 3/18/2008 9:50 PM
Gravatar I haven't spent any time with the DbDataContext, but I'll bite. Agreed, attaching it to the current thread would be bad, especially in situations such as ASP.NET where you don't control the threading model directly. One model might be to create some type of session within your Unit of Work that manages multiple context internally (think local data slots), finally allowing the user to vote on the committing the changes, etc when Dispose is called.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by sodablue at 3/18/2008 10:25 PM
Gravatar I was interested in something very similar, and I adapted code from the BackgroundMotion sample app.

http://www.backgroundmotion.com

It was created by a couple of guys from Microsoft New Zealand. I replaced the dependency injection scheme they were using with Unity, and eliminated some of the singletons it appeared to be using in favor of a creation upon request, just because I wasn't sure it was safe.

I felt it was a creative approach. Not only do they have a UnitofWork pattern wrapper for Datacontext, which basically does a submitchanges() automatically when it disposes out of the using {} block, it also has a generic Repository wrapper such that you can very easily mock out the LINQ to SQL and replace it with a in-memory database.

I just started working with it, and haven't explored the limitations but it's something to look at for ideas.

Also read this blog post on the Repository Abstraction they used
http://andrewpeters.net/2007/04/28/fixing-leaky-repository-abstractions-with-linq/

I'm using the MVC framework and i basically create a single context by way of this uow wrapper within my controller method and then do everything at once. So I don't find I have to pass things around.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Emanuele DelBono at 3/19/2008 4:25 AM
Gravatar I had the same problem with Nhibernate: how to manage the Session lifetime?
I used an approach similar to 3 (Ambient DataContext). I create the concept of Conversation: in a Web application a conversation start at the begin of request and stop ath the end (Pattern: Open Session in View).
In Windows Application is more difficult, because more conversations could start at the same time, I create a session for every conversation where a conversation is a "user story" (a bunch of windows that do something: for example show customers list and manage them)

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Bigyan Rajbhandari at 3/19/2008 8:41 AM
Gravatar I had asked this same question to Dino Espositos in reference to his latest article on DataContext.

http://dotnetslackers.com/articles/csharp/InsideTheLINQToSQLDataContextClass.aspx

He posted a reply on his blog regarding this. Take a look.

http://weblogs.asp.net/despos/archive/2008/03/19/more-on-datacontext-in-hopefully-a-realistic-world.aspx

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Bernal Schooley at 3/19/2008 8:58 AM
Gravatar Anyone reading this should also read this blog post (http://weblogs.asp.net/despos/archive/2008/03/19/more-on-datacontext-in-hopefully-a-realistic-world.aspx) by Dino Esposito on this topic.

The short of it from my perspective is that the DataContext is light for purposes of creation but once used is "not-so-light" and thus should not be persisted. You will also run into problems if you use long lived DataContexts in an active multi-user environment because the DataContext caches objects which can easily lead to concurrency issues that are hard to debug.

I'd like to re-emphasize Dino's suggestion that the DataContext only live for a single unit-of-work and I'll add that you should keep your definition of a unit-of-work as narrow as possible. To be specific, a unit-of-work should not be considered (in the scope of ASP.Net for instance) so big that it encompases all database activity for a full web page call. Rather, it should be alot smaller in practice. For instance, a good rule in many (but not all) cases might be to limit the scope to the method in which it is used.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Ben at 3/19/2008 5:15 PM
Gravatar Quote: "Dino's suggestion that the DataContext only live for a single unit-of-work"

I came here looking to rid myself of #1 and found #3!

If I take Dino's advice, this mean I am sticking to using #1?

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Bigyan Rajbhandari at 3/20/2008 4:56 PM
Gravatar Thanks everyone for the feedback, here's what I have taken from the read.

http://www.dotnetlog.com/archive/2008/03/20/follow-up--best-practice-and-effective-use-of-datacontext.aspx

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by turkey at 7/31/2008 1:05 AM
Gravatar Thanx You.. Perfect Docs

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Developmentalmadess at 9/19/2008 11:42 AM
Gravatar Here's what we've been doing, but I'll read up on Dino's blog and the followup posted here. As we're working on incorporating our method with WPF apps we're trying to determine if #3 (essentially what we're doing) is the best method: http://developmentalmadness.blogspot.com/2008/07/linq-to-sql-reusing-datacontext.html

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Frank Schwieterman at 12/17/2008 2:54 PM
Gravatar The solution is #1.

I do not think passing around the datacontext as a parameter is a big problem, a molehill only make it a mountain if you wish. But do be judicious about when you pass it around- don't just pass it in because you know the caller will need a datacontext to use (this would be an optimization that introduces inappropriate coupling). You should only pass it around when the semanantics of the function involve really sharing that context.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Rick O'Shay at 4/14/2009 12:13 PM
Gravatar When will Microsoft stop with the "sour grapes" response to the myriad, proven, material benefits provided by IoC containers like Java EE (totally annotation based), SEAM and Spring? They are just now getting around to providing technologies like MVC (a candidate for Technology of the Ancients on the Discovery Channel).

[DataContext] context; // let the container figure it out, then inject.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by software development company at 8/14/2009 3:19 AM
Gravatar Hey, that was interesting,

I had the same problem with Nhibernate: how to manage the Session lifetime?
I used an approach similar to 3 (Ambient DataContext). I create the concept of Conversation: in a Web application a conversation start at the begin of request and stop ath the end (Pattern: Open Session in View).


Thanks for bringing this up

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by Altın Fiyatları at 9/14/2009 1:35 AM
Gravatar Thanks for your post informing.

# re: Best practice and effective way of using DataContext in Linq to SQL?

Left by speelautomaten at 12/18/2009 4:27 AM
Gravatar I have one problem. I am using static Datacontext Variable. it works fine.. But sometime i got error on website, e.g.
Datareader is already open.. then my website goes down for you say 4-5 minutes.. It works fine again..Is this due to connection pooling?
Plese suggest me..

Your comment:





 
Please add 2 and 5 and type the answer here:

Copyright © Bigyan Rajbhandari