LinqConnect Documentation
Lazy Loading

Lazy loading is the pattern that is used to defer initialization of an object until this object is really needed by application. It is an opposite to the eager loading pattern, which supposes the immediate object initialization. In LinqConnect, lazy loading can be used for relationships and 'plain' entity fields.

Relationships

Lazy loading is enabled by default for entity relationships in LinqConnect. Now we describe how it works.

Note:
The lazy loading functionality is only available for references that have navigation properties of the EntitySet/EntityRef types. For IList and 'plain entity' navigation properties of POCO classes, only eager loading can be used.

Suppose a table is linked to another one (for example, 'Order Detail' and 'Order' from the CRM Demo sample database) via a foreign key. The corresponding entity classes should have a one-to-many association; i.e., we can think that each Order instance has a collection (possibly empty) of OrderDetail objects. To simplify accessing this collection, the code-generation templates create the OrderDetails property in the Order class (and the Order property in the OrderDetail class to navigate in the reverse direction). Such properties are called navigation properties.

Though it is convenient to get the collection of related objects via a property, you probably don't want to fetch and materialize all the related details each time you get the information about a particular order (specifically, this would cause materializing entities related to these details, and so on). Thus, the related entities are not fetched until you explicitly address to the corresponding collection:


C#csharpCopy Code
var orderQuery = from order in context.Orders
                 where order.ShipDate.Value.Year == 2007
                 select order;
// At this point, order details are not retrieved.
var orders2007 = orderQuery.ToList();

foreach (Order order in orders2007)
{
    double sum = 0;
    // And now LinqConnect do get the details from the database.
    foreach (OrderDetail detail in order.OrderDetails)
        sum += detail.Price.GetValueOrDefault();
    Console.WriteLine("Order {0}, total cost: {1}$.", order.OrderID, sum);
}
Visual BasicCopy Code
Dim orderQuery = From order In context.Orders _
                 Where order.ShipDate.Value.Year = 2007 _
                 Select order
' At this point, order details are not retrieved.
Dim orders2007 = orderQuery.ToList()

For Each order As Order In orders2007
    Dim sum As Double = 0
    ' And now LinqConnect do get the details from the database.
    For Each detail As Orderdetail In order.Orderdetails
        sum += detail.Price.GetValueOrDefault()
    Next
    Console.WriteLine("Order {0}, total cost: {1}$.", order.OrderID, sum)
Next

The same is applicable to the navigation properties used to access a single entity instead of a collection (e.g., the Order property of the OrderDetail class): until you directly refer to such a property, no query is performed to get the order from the database.

In some scenarios, however, you do want to get all related entities when fetching the 'main' one. For the details on performing such a task, refer to the Eager Loading topic in this section.

Simple Fields

By default, all entity fields are loaded eagerly, since this suits most common situations. However, in some cases you may want to change this behaviour. For example, when only a part of columns is bound to a grid, there is no point to fetch the other part for the whole displayed record set. Or, if a table has a large binary column (e.g., Oracle BLOB or SQL Server 'image'), one has to fetch few megabytes of binary data for just doing several changes to the columns of 'simple' types if the delay loading is not enabled for this column.

To specify that a column should be delay loaded, define this field as Devart.Data.Linq.Link<field type> Or, if using Entity Developer, set the 'Delay Loaded' property of the corresponding entity member to 'true' in your model, and Entity Developer will generate the code on its own.

Note:
If several columns are marked to be delay loaded, and you refer to one of them in your code, only this particular column is being fetched. If you want to access a set of delay loaded columns simultaneously, consider implementing a Table-Per-Hierarchy inheritance instead.

Technical details

For those interested in the implementation details: LinqConnect uses the following wrapper class and structures to provide the lazy loading feature: