// 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();
}
}
}
Comments