0

I have a controller and two actions.

In my Products action I am filling my collection. And then when I call Index action, ProductManager.ReadProducts() method called again.

I don't want to connect to the database on second action call.

public class ProductController : Controller
{
    public List<Product> ProductsList = ProductManager.ReadProducts();

    public ActionResult Index(long Id)
    {
        return View(ProductsList.FirstOrDefault(x => x.Id == Id));
    }

    public ActionResult Products()
    {
        return PartialView(ProductsList);
    }
}
ekad
  • 14,436
  • 26
  • 44
  • 46
Armen Mkrtchyan
  • 921
  • 1
  • 13
  • 34
  • Not quite sure what the problem is. Do you say that you get two DB connections? Or two DB queries? Or you want to cache in memory the DB results? Either way, please add more code that's relevant to your question. – Cristik Apr 15 '15 at 07:49
  • 3
    Why not? You need to get the values from somewhere. You could always cache them somewhere, e.g. use Session –  Apr 15 '15 at 07:50
  • it's ok to cache large data (100 rows of some data), or it's better to request one row data every time?? – Armen Mkrtchyan Apr 15 '15 at 08:02

2 Answers2

4

As @stephen-muecke mentioned you have few solutions

Solution 1: Session but keep in mind that Session is per user. If your products are user specific you can use it.

public class ProductController : Controller
{
    public List<Product> ProductsList {
            get { 
                var products = (Session["ProductsList"] as List<Product>);
                if(products == null)
                {
                    products = ProductManager.ReadProducts();
                    Session["ProductsList"] = products;
                }

                return products;
            }
        }

    // actions
}

Solution 2: Caching which is for all users, if your products are for all users you store in a single place for all of them.

public class ProductController : Controller
{
    public List<Product> ProductsList {
            get { 
                var products = (HttpRuntime.Cache["ProductsList"] as List<Product>);
                if(products == null)
                {
                    products = ProductManager.ReadProducts();
                    HttpRuntime.Cache["ProductsList"] = products;
                }

                return products;
            }
        }

    // actions
}

Solution 3: You can make use of OutputCache to cache the output of actions.

public class ProductController : Controller
{
    public List<Product> ProductsList = ProductManager.ReadProducts();

    [OutputCache(Duration=60, VaryByParam="*")] 
    public ActionResult Index(long Id)
    {
        return View(ProductsList.FirstOrDefault(x => x.Id == Id));
    }

    [OutputCache(Duration=60, VaryByParam="none")]
    public ActionResult Products()
    {
        return PartialView(ProductsList);
    }
}
Community
  • 1
  • 1
adricadar
  • 9,971
  • 5
  • 33
  • 46
2

Use one of the shared container, for example Session

public class ProductController : Controller
{
    public ActionResult Index(long Id)
    {
        return View(GetProductList().FirstOrDefault(x => x.Id == Id));
    }

    public ActionResult Products()
    {
        return PartialView(GetProductList());
    }

    private IList<Product> GetProductList()
    {
        var productList = Session["ProductsList"];

        if (productList != null)
        {
            return productList;
        }

        productList = ProductManager.ReadProducts();
        Session["ProductsList"] = productList;

        return productList;
    }
}
Igor Semin
  • 2,486
  • 1
  • 20
  • 21
  • it's ok to cache large data (100 rows of some data), or it's better to request one row data every time?? – Armen Mkrtchyan Apr 15 '15 at 08:04
  • 1
    @Armen why not? if you don't want make mass request for db you must use cache - session(if your server is allow) or redis for local cache data on server – Igor Semin Apr 15 '15 at 08:10