2

I have a dropdown menu that when you select an option value submit the form, and to avoid repetitive database calls I am storing my non-sensitive object in a session.

private List<Employee> stafflist
{
    get { return Session["stafflist"] as List<Employee>; }
    set { Session["stafflist"] = new Employee(); }
}
private void RemoveStaff()
{
    Session.Remove("stafflist");
}

however in my

[HttpPost]
public ActionResult index (...)
{
    //why can't I get the list of staff like this?
    ViewBag.staff=stafflist.Where(..).toList();

    //is the below still needed? i thought i 
    //have a session variable declare above, 
    //and to avoid 30x repetitive db calls? 
    //also note when i include the below the code runs fine, 
    //however, if i take it out it doesn't. i would like to avoid repetitive db calls
    stafflist=db.Employee.toList(); 
}
7
  • "why can't I get the list of staff like this?" - please post the exact error and share your research for it? Also, if you never assign to the stafflist member earlier, it's null... Commented Mar 24, 2016 at 18:57
  • @CodeCaster i only get an null value when i am not using stafflist=db.Employee.toList(); however, if i include this, code is fine. i guess i want to understand the process of storing an object in a session to avoid repetitive database calls? Commented Mar 24, 2016 at 18:59
  • In order to get something out of a reference, you first have to store something in it... So you'll need to store it at least once. Commented Mar 24, 2016 at 18:59
  • @CodeCaster where do i store it? is it inside my private method? thanks. i want to avoid any calls to the database. thanks. Commented Mar 24, 2016 at 19:01
  • You cannot avoid any calls to the database, you need to query it at least once. When to do so, depends on how the rest of this application is set up. You could do it on the first GET call to Index, for example. Commented Mar 24, 2016 at 19:02

3 Answers 3

3

First of all, you should not prevent to query the database. Proper caching is hard to get right, and a database is perfectly capable of performing queries and caching data.

If you're absolutely sure you want to circumvent the database, and query clientside (i.e. in the controller) then you need to pull the entire staff list from the database at least once per visitor.

You could do that in the first GET call to this controller, assuming the user will always visit that:

[HttpGet]
public ActionResult Index (...)
{
    var cachedStaff = db.Employee.toList(); 
    Session["stafflist"] = cachedStaff;
}

Then in the POST, where you actually want to do the database query (again, consider letting the database do what it's good at), you can query the list from the session:

[HttpPost]
public ActionResult Index (...)
{
    var cachedStaff = Session["stafflist"] as List<Employee>();

    // TODO: check cachedStaff for null, for when someone posts after 
    // their session expires or didn't visit the Index page first.

    var selectedStaff = cachedStaff.Where(..).ToList();

    // the rest of your code
}

Then the property you introduced can be used as syntactic sugar to clean up the code a bit:

private List<Employee> CachedStaff
{
    get { return Session["stafflist"] as List<Employee>; }
    set { Session["stafflist"] = value; }
}

[HttpGet]
public ActionResult Index (...)
{
    CachedStaff = db.Employee.toList(); 
}

[HttpPost]
public ActionResult Index (...)
{
    // TODO: this will throw an ArgumentNullException when
    //  the staff list is not cached, see above.
    var selectedStaff = CachedStaff.Where(..).ToList();

    // the rest of your code
}
Sign up to request clarification or add additional context in comments.

2 Comments

@Menew I think the bigger picture you're missing is spelled out quite explicitly in my answer: you don't want to prevent querying the database. You don't want to pull in the entire table in the session for each visitor.
so you are saying to let the db do its job? which way is better? the data that i am caching is not that important, more like city names. thanks.
0

A session is unique for the current user and the current session. That means that when the user closes the browser, the session information is lost. The session is also lost if the session cookie is removed. Read about state management.

If you want to have a global staff list that is available for all users you need to use something else. Caching is the most common case then.

Comments

0

you probably have it already figured it out, just in case I leave here what it worked for me.

First you create a new session variable based on an object created (in this case the object usr will be empty):

User usr = new User();
Session["CurrentUSR"]=usr;

where you want to use the new object, you will have to cast the session variable and point it to a new object created in that particular page:

User usr= new User(); //at this point the usr object is empty, now you are going to replace this new empty object with the session variable created before
usr=Session["CurrentUSR"] as User();

In case you have a list, the best course of action would be to create a List<> of that particular object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.