views:

413

answers:

6

hello all,

I'm working with linq to sql, and therefore need to store my DataContext for future use for each thread (I've read this article: http://www.west-wind.com/weblog/posts/246222.aspx regarding ways to implement a shared context). What I want to know though, is how do I create a single key that both the global.asax file will know and so will the webpage without hardcoding it, and if i do hardcode it the key must be specific for each user.

Thank you very much!

Vondiplo

A: 

Well it sounds like you want to look at Page.Cache. This is a collection that is available at an application level. It is available in all sessions for all users.

Andrew Hare
A: 

Add the DataContext into request scope:

In global.asax.cs:

HttpContext.Current.Items["HardcodedKey"] = dataContext;

In the page:

DataContext dc = (DataContext) HttpContext.Current.Items["HardcodedKey"];

The .Items collection is scoped to an individual request, so for a given key, each request will reference a different item.

Sean Reilly
A: 

Wow Thank you both for the fast response.

Well I cannot use session in the global asax, so that option is off... As to the second option of using HttpContext.Current.Items[], I'd rather not handle the datacontext for each request, I'd rather have it a longer life time, say... for the remaining of the session. is that possible?

My mistake - I removed my reference to Page.Session.
Andrew Hare
A: 

Ah Thank's Andrew, though then I will be facing the problem of needing to find a unique id that both the page and the global asax know and share for each session. Normally I'd take the user ID as the what I am looking for is a per user scenario. Though I use the global asax to retrieve the user in the firstplace, and I need the datacontext to perform the select operation on. Which means that I need to find another mutual key... any ideas?

A: 

Not sure why you can't use session in Global.asax - you just need to ensure you're calling it from the right place.

By default, there's very little in the Global.asax, but there are a number of methods you can implement if you want, and you'll probably want something along the lines of (tested locally):

void Session_Start(object sender, EventArgs e) 
{
    // Code that runs when a new session is started
    // Pick up your session id here, create a new context and away you go?

    var sessionId = Session.SessionID;

    Session.Add("sessionId", sessionId);
}

void Session_End(object sender, EventArgs e) 
{
    // Code that runs when a session ends. 
    // Note: The Session_End event is raised only when the sessionstate mode
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised.

    // Noting comment above, clean up your context if needs be.
}

Then in your site you can have something like:

protected void Page_Load(object sender, EventArgs e)
{
    Literal1.Text = Session["sessionId"].ToString();
}

I'm not sure that Session is the right place for you to store this, and you'll want to do some performance testing to see if it's going to handle the sorts of loads you are expecting.

Zhaph - Ben Duguid
+1  A: 

Have you considered something like the IContainerAccessor from the Castle.Windsor framework?

Then you can do something like

   public class GlobalApplication : System.Web.HttpApplication, IContainerAccessor
   {
     private static readonly WindsorContainer _container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

     public IWindsorContainer Container
     {
         get { return _container; }
     }
   }

With Container becoming accessible through the entire app like

   var accessor = HttpContext.Current.ApplicationInstance as IContainerAccessor;
   var controller = accessor.Container.Resolve<IDataContext>("myDataContext");

This will require some research into Castle Windsor and its IoC capabilities, but imo they will be very useful to you.

JamieF