views:

33

answers:

0

My .NET MVC project has reached the stage of testing with multiple users and I am getting seemingly random errors (from any screen in the site) relating to Linq2Sql DataReader issues, such as:
'Invalid attempt to call FieldCount when reader is closed.' and
'ExecuteReader requires an open and available Connection. The connection's current state is closed.'
These errors are also appearing less frequesntly during single user testing if a link is double-clicked or when multiple tabs in the browser, or different browsers are refreshed simultaneously.

I'm wondering if these issues are down to DataContext threading problems.

At the moment I am using the repository approach with seperate repositories for each business process. Each repository class fires up a DataContext instance in its contructor and this is used by most methods in the repository.
However some methods are updating the DataLoadOptions to force eager loading of view data so these methods create their own instance of the DataContext.
Also on some screens there is information from multiple business objects displayed so there may be 2 or 3 repositories involved in a single request. Consequesntly there could be many seperate DataContext instances created per request.
I've tried to enforce an eager loading approach throughout using DataLoadOptions where necessary and applying ToList() on query results to make sure everything is loaded up front (not waiting until the view is rendered) - so each DataContext should only be open for a fairly short period.

As the errors appear to be related to multiple threads reusing the same DataContext(s), I'm thinking of implementing a single DataContext per request along the lines of Rick Strahl's Thread Specific DataContextFactory (http://www.west-wind.com/weblog/posts/246222.aspx) or a simpler “unit of work datastore” approach as in Steve Sanderson's example (http://blog.stevensanderson.com/2007/11/29/linq-to-sql-the-multi-tier-story/).

But then there's the issue of DataLoadOptions to resolve. I could create additional thread-specific DataContexts but that seems to be getting away from my goal of using a single DataContext per request. So I'm looking at either reusing the same DataContext but temporarily changing the LoadOptions for some methods as in Kevin Watkin's example (http://www.mrkwatkins.co.uk/Blog/2010/05/)
or scrapping the standard DataLoadOptions approach in favour of using preload stored procedures to pre-populate EntityRefs as discussed by Roger Jennings in Visual Studio magazine (http://visualstudiomagazine.com/Articles/2007/11/01/Optimize-LINQ-to-SQL-Performance.aspx?Page=3)

So my question is has anyone experienced similar random DataReader issues, how did you resolve them, and am I likely to resolve the problem by implementing those solutions I've linked to?

As always time is tight - so I don't want to spend it implementing a solution if the problem is actually somewhere else. Any help would be greatly appreciated!

PS. I'm afraid this is quite a high-level question and I haven't included any specific code examples as I'm not sure where the problem actually lies.