// From http://www.developmentalmadness.com/2008/07/28/linq-to-sql-reusing-datacontext/ /************************************************************************************** * IThreadLocalStorageProvider.cs **************************************************************************************/ namespace MyApp.Web.Models { public interface IThreadLocalStorageProvider { void SaveItem(string key, object value); object GetItem(string key); bool ContainsItem(string key); } public class ThreadLocalStorageProviderFactory { public static IThreadLocalStorageProvider Current { get; set; } } } /************************************************************************************** * WebThreadLocalStorageProvider.cs **************************************************************************************/ namespace MyApp.Web.Models { using System.Web; public class WebThreadLocalStorageProvider : IThreadLocalStorageProvider { public void SaveItem(string key, object value) { HttpContext.Current.Items.Add(key, value); } public object GetItem(string key) { return HttpContext.Current.Items[key]; } public bool ContainsItem(string key) { return HttpContext.Current.Items.Contains(key); } } } /************************************************************************************** * MyAppDataContext.cs (partial class) **************************************************************************************/ namespace MyApp.Web.Models { using System; using System.Collections.Generic; using System.Data.Linq; public partial class MyAppDataContext { public static MyAppDataContext GetDataContext() { // if TLS isn't available just return a new DataContext if (ThreadLocalStorageProviderFactory.Current == null) return new MyAppDataContext(); MyAppDataContext context; // check to see if DataContext already exists in TLS if (ThreadLocalStorageProviderFactory.Current.ContainsItem("DataContext")) { // get DataContext context = ThreadLocalStorageProviderFactory.Current.GetItem("DataContext") as MyAppDataContext; // verify DataContext if (context != null) return context; } // if we got here, then just create a new DataContext context = new MyAppDataContext(); // cache the DataContext ThreadLocalStorageProviderFactory.Current.SaveItem("DataContext", context); // return to caller return context; } } } /************************************************************************************** * Global.asax.cs **************************************************************************************/ namespace MyApp.Web { using System; using System.Data; using System.Data.Linq; using System.Security.Principal; using System.Web; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using System.Web.Security; using MyApp.Web.Models; public class MvcApplication : System.Web.HttpApplication { protected void Application_EndRequest(object sender, EventArgs e) { // Validate that we actually have a DataContext to evaluate. if (!ThreadLocalStorageProviderFactory.Current.ContainsItem("DataContext")) return; // Create an instance of the DataContext var ctx = ThreadLocalStorageProviderFactory.Current.GetItem("DataContext") as DataContext; // If the instanciated DataContext is not null and connected, destroy it. if (ctx != null && ctx.Connection.State == ConnectionState.Open) ctx.Dispose(); } } }