C# Code, Tutorials and Full Visual Studio Projects

Lazy Loading in C#

Posted by on Nov 18, 2010 in Code Snippets | 5 comments

Lazy Loading in C#

C# comes with built-in Lazy loading for those of us who are … well Lazy.  The .NET function is simply called Lazy and here is one easy way to use it in your projects.

Suppose you have a List of customers and each customer had a list of purchase orders associated with that customer.  When loading the customer you would need to goto your PurchaseOrders table and load the purchase orders associated with that customer.  This gets to be quite a bit of data if you have thousands of customers each with hundreds of purchase orders.

Lazy loading to the rescue!  Lazy loading will let you defer loading the purchase orders on each of your customers until those purchase orders are needed.  This means that your program will load faster cause it only needs to load the customers and not the purchase orders, but that it will take a small performance hit each time the operator of your program views a customers purchase orders.  Now considering that the operator would never view all the purchase orders of the thousands of customers Lazy loading will save the operator time and resources.

Here is an example, I will explain below, but pay special attention to the Customer Class’s PurchaseOrder property, it’s where the magic is.

Customer Class

using System;
using System.Collections.Generic;

namespace Jarloo
{
    public class Customer
    {
        public int Id { get; private set; }
        public Lazy<List<PurchaseOrder>> PurchaseOrders { get; private set; }

        public Customer(int id)
        {
            Id = id;
            PurchaseOrders = new Lazy<List<PurchaseOrder>>(() => PurchaseOrderFactory.GetOrders(Id));
        }
    }
}

Purchase Order Class

using System;

namespace Jarloo
{
    public class PurchaseOrder
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime Timestamp { get; set; }
    }
}

Purchase Order Factory

using System;
using System.Collections.Generic;

namespace Jarloo
{
    public class PurchaseOrderFactory
    {
        public static List<PurchaseOrder> GetOrders(int id)
        {
            //Normally you could query the db here to get the details
            //instead in this example we return the same stuff per customer id

            Console.WriteLine("Creating Purchase Orders");

            List<PurchaseOrder> orders = new List<PurchaseOrder>();

            for (int i = 0; i < 20; i++)
            {
                PurchaseOrder o = new PurchaseOrder();
                o.Id = i;
                o.ProductName = "Test";
                o.Quantity = 5 + i;
                o.Timestamp = DateTime.Now;
                orders.Add(o);
            }

            return orders;
        }
    }
}

Main Method

using System;

namespace Jarloo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Customer cust = new Customer(10);

            Console.WriteLine("IsValueCreated=" + cust.PurchaseOrders.IsValueCreated);

            int count = cust.PurchaseOrders.Value.Count;

            Console.WriteLine("IsValueCreated=" + cust.PurchaseOrders.IsValueCreated);

            Console.ReadLine();
        }
    }
}

So when we query our customer object and check the IsValueCreated property it will return “false”. Then once we access it in anyway such as getting the count of objects, the Lazy type will invoke the function we gave it which is our factory, and the factory will return the purchase orders. So when we check the IsValueCreated again it is now “true” since the initialization of our PurchaseOrders property has occurred.

There are several other overrides you can explore if this one on the Lazy<> type doesn’t meet your needs.

5 Comments

Join the conversation and post a comment.

  1. celmis

    how about Lazy<List> as frill

  2. celmis

    ohh … your syntax checker has problems with generic expressions …

  3. kelias

    Your right it’s messing up the code there. I’ll look into it. Thanks!

  4. kelias

    With some spaces it turns out ok. Odd but gets the job done.

  5. Veronica Luna

    Solo quiero comentar que este post esta buenisimo y que me fue de mucha ayuda, ademas de que deseo darle las gracias al autor de este post y seguir animandolo para que siga reaizando post tan educativos e instructivos como este.

Leave a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>