Ricketts
Ricketts

Reputation: 5213

Thoughts on storing entire LINQ objects in session?

I wanted to get some feedback on your thoughts of storing entire objects into a session? For example, a customer object. Once a customer logs into their control panel, instead of re-fetching their data each time it is needed from a ID stored in a session, what are the pros and cons of storing the entire customer object in a session?

So anytime you needed to reference the customer object, you could just do:

Customer c = (Customer)Session["objCustomer"];

Obviously, you would need to check and have a function that refreshes the session. You would need to run this function in the case of a null session or after an update is made.

Aside of that, is there any other issues I should be aware of doing it this way? It seems this would be much better as far as programming and also make far less calls to the database. Thoughts anyone?

Upvotes: 3

Views: 1089

Answers (3)

Jonjojr
Jonjojr

Reputation: 1

mellamokb I agree with your point of bringing in the properties that you need. you can do that by adjusting the model, and you can also turn off lazy loading. Other than that I think it is pretty safe. Unless we are storing all of these objects as references then no there is no problem these objects are on their own once placed in the session. the only time that you may cause a problem is if both contexts are in scope.

Upvotes: 0

Katie Kilian
Katie Kilian

Reputation: 6983

I have run into the issue described by Wiktor in another answer. I use NHibernate, and if you store objects in the session, you will get issues comparing them, issues with disconnected sessions, etc. Nonetheless, I go ahead and store my objects in session. I just make sure they all implement their own Equals() and GetHashCode() functions. That way I can compare objects from different session to see whether they are the same object. I make it a habit to use obj1.Equals(obj2) instead of obj1 == obj2.

Of course, there are always trade offs -- you gain the speed of not having to repeat the query, versus gaining complexity in your code. Which way is right for you depends on the particulars of your situation.

Upvotes: 2

Wiktor Zychla
Wiktor Zychla

Reputation: 48279

This is not a good idea.

The main reason for that is the way ORMappers works - they don't like it when you mix objects from different contexts. And this would happen in the scenario you propose - you have an object in the session, created by a different context your next (and following) requests use. Sonner or later you would start to get exceptions.

Personally I prefer an approach where a simple object containing the Customer's ID (and probably other attributes) is stored in a session (or in the custom data section of the forms cookie) and I wrap the access to the customer object in a simple statement which involves the Items container:

(a production code would require few checks here and there to be more defensive):

const string CUSTOMERITEM = "customeritem";
public Customer Current
{
    get
    {
        if ( HttpContext.Current.Items[CUSTOMERITEM] == null )
        {
           int id = retrieve_the_id;

           using ( DbContext ctx = GetCurrentDbContext() ) 
           {
               HttpContext.Current.Items.Add( CUSTOMERITEM, ctx.Customers.FirstOrDefault( c => c.ID == id );
           }
        }
        return (Customer)HttpContext.Current.Items[CUSTOMERITEM];
    }
}

Items container lasts only for the time of one request. The snippet above makes sure that the object is loaded only once per request.

Of course, this comes with a price of one additional query per request comparing to your approach. But the advantage is that you never mess up database contexts.

Note that there are some business processes which don't require the Customer object but you can pass the customer's ID directly and use in queries:

 public IEnumerable<Order> CustomerOrders( int CustomerID ) 
 {
     // use the customer id directly, without first loading the customer object
 }

Upvotes: 7

Related Questions