Deferred versus Immediate Loading

When you query for an object, you actually retrieve only the object that you requested. The related objects are not automatically fetched at the same time. You cannot see the fact that the related objects are not already loaded, because an attempt to access them produces a request that retrieves them.

For example, you might want to query for a particular set of orders and then to occasionally send an e-mail notification to particular customers. You would not necessarily need to initially retrieve all customer data with every order. You can use deferred loading to defer retrieval of extra information until you absolutely have to. Consider the following example:

C#


    using (NorthwindDbContext dbContext = new NorthwindDbContext())
    {
       IQueryable<Order> query = from o in dbContext.Orders
                                               where o.ShipVia == 1
                                               select o;
       foreach (Order order in query)
       {
           // Process order...
       }
    }

VB.NET


    Using dbContext As New NorthwindDbContext()
     Dim query As IQueryable(Of Order) = From o In dbContext.Orders
                                         Where o.ShipVia = 1
                                         Select o
     For Each order_Renamed As Order In query
      ' Process order...
     Next order_Renamed
    End Using

The opposite might also be true. You might have an application that has to view customer and order data at the same time. You know that you need both sets of data. You also know that your application needs order information for each customer as soon as you get the results. You would not want to submit individual queries for orders for every customer. What you really want is to retrieve the order data together with the customers.

C#


    using (NorthwindDbContext dbContext = new NorthwindDbContext())
    {
       Telerik.OpenAccess.FetchOptimization.FetchStrategy fetchStrategy = new Telerik.OpenAccess.FetchOptimization.FetchStrategy();
       fetchStrategy.LoadWith<Customer>(c => c.Orders);
       dbContext.FetchStrategy = fetchStrategy;

       IQueryable<Customer> query = from c in dbContext.Customers
                                       where c.Country == "Germany"
                                       select c;
    }

VB.NET


    Using dbContext As New NorthwindDbContext()
     Dim fetchStrategy As New Telerik.OpenAccess.FetchOptimization.FetchStrategy()
     fetchStrategy.LoadWith(Of Customer)(Function(c) c.Orders)
     dbContext.FetchStrategy = fetchStrategy
     Dim query As IQueryable(Of Customer) = From c In dbContext.Customers
                                            Where c.Country = "Germany"
                                            Select c
    End Using

You can also join customers and orders in a query by forming the cross-product and retrieving all the relative bits of data as one large projection. But these results are not entities. Entities are objects that have identity and that you can modify, whereas these results would be projections that cannot be changed and persisted. Even worse, you would be retrieving lots of redundant data as each customer repeats for each order in the flattened join output.

What you really need is a way to retrieve a set of related objects at the same time. The set is a delineated section of a graph so that you would never be retrieving more or less than what's necessary for your intended use. For this purpose, Telerik Data Access provides FetchStrategy for immediate loading of a region of your object model. Methods include:

  • The LoadWith method, to immediately load data related to the main target.

See Also