How to perform Lazy Loading with entities(POCO) in Entity Framework 4.0
Lazy Loading is one of the patterns we use to load related entities using navigation properties. By default, Entity Framework supports LazyLoading for generated EntityObject classes. The navigation properties of EntityObject classes return either Entity collections or EntityReferences. If you observe the POCO class given below, the navigation property SalesOrders returns the collection of SalesOrder objects. In the class, we have used ICollection (interface) to return the collection. We use ICollection instead of IList for the flexibility we get when we consume the class. The EntiyCollection and ICollection are two different things. We get these capabilities only with the EntityCollection class but not with ICollection. This is why we cannot perform Lazy Loading automatically.
The following code defines a class(POCO) of a Customer.
To get LazyLoading, we need to declare a navigation property as virtual, public and also as a collection which implements ICollection<T> interface as shown in above code. By making a navigation property as virtual, the EF runtime creates proxies. As shown, if we declare all the properties as virtual, entity framework creates change tracking proxies which handle change notification, lazy loading and relationship fix-up automatically. If we declare only navigational properties as virtual, EF creates proxies and we get only loading(lazy) capability.
The advantage we get by specifying only navigational properties as virtual is Entity Framework will not generate change tracking proxies and entities rely on snapshot notification mechanism to synchronize data with ObjectStateManager. This is essentially required in enterprise application development. In case of EntityObject classes, this feature can be enabled at the context level and so we do not have much control.
But with POCOs, we can specify which navigation properties are lazy-loaded so we get more control. Note that when we use this pattern, all the related entities are retrieved from the database. After retrieving all the data, any filtering can be done locally. The statement customer.SalesOrders.First() retrieves all the sales orders from the database and then the method First() will be applied on data.
After we declare the navigation property as virtual, we need to enable by setting ContextOptions of the ObjectContext and ProxyCreationEnabled to true as shown below. After the LazyLoadingEnabled property is set to true, we can perform Lazyloading with POCOs.
ctx.ContextOptions.LazyLoadingEnabled = true;
ctx.ContextOptions.ProxyCreationEnabled = true;
Example code
If you execute the above code, all the sales orders of the customer with id 16 are loaded as shown in figure below.
If you have come to this page directly, you may want to know How to Create a POCO class in entity framework.
The main objects in the above example - customers are returned by a query and related objects are loaded with navigation properties automatically without writing a query. This means that we cannot retrieve both main and related objects at once and there is a delay in loading related data. This is the reason why it is also called as deferred loading. The code c.SalesOrders performs a query automatically to retrieve sales orders related to a particular customer even though we have not written any query.
If LazyLoadingEnabled property is set to false, the sales orders for a customer will not be displayed. You will see that this code is written in the same way as for EntityObjects. The relevant article is here - Loading Related entities in Entity Framework.
The following code defines a class(POCO) of a Customer.
To get LazyLoading, we need to declare a navigation property as virtual, public and also as a collection which implements ICollection<T> interface as shown in above code. By making a navigation property as virtual, the EF runtime creates proxies. As shown, if we declare all the properties as virtual, entity framework creates change tracking proxies which handle change notification, lazy loading and relationship fix-up automatically. If we declare only navigational properties as virtual, EF creates proxies and we get only loading(lazy) capability.
The advantage we get by specifying only navigational properties as virtual is Entity Framework will not generate change tracking proxies and entities rely on snapshot notification mechanism to synchronize data with ObjectStateManager. This is essentially required in enterprise application development. In case of EntityObject classes, this feature can be enabled at the context level and so we do not have much control.
But with POCOs, we can specify which navigation properties are lazy-loaded so we get more control. Note that when we use this pattern, all the related entities are retrieved from the database. After retrieving all the data, any filtering can be done locally. The statement customer.SalesOrders.First() retrieves all the sales orders from the database and then the method First() will be applied on data.
After we declare the navigation property as virtual, we need to enable by setting ContextOptions of the ObjectContext and ProxyCreationEnabled to true as shown below. After the LazyLoadingEnabled property is set to true, we can perform Lazyloading with POCOs.
ctx.ContextOptions.LazyLoadingEnabled = true;
ctx.ContextOptions.ProxyCreationEnabled = true;
Example code
If you execute the above code, all the sales orders of the customer with id 16 are loaded as shown in figure below.
If you have come to this page directly, you may want to know How to Create a POCO class in entity framework.
The main objects in the above example - customers are returned by a query and related objects are loaded with navigation properties automatically without writing a query. This means that we cannot retrieve both main and related objects at once and there is a delay in loading related data. This is the reason why it is also called as deferred loading. The code c.SalesOrders performs a query automatically to retrieve sales orders related to a particular customer even though we have not written any query.
If LazyLoadingEnabled property is set to false, the sales orders for a customer will not be displayed. You will see that this code is written in the same way as for EntityObjects. The relevant article is here - Loading Related entities in Entity Framework.
More Resources
- POCO class in Entity Framework
- POCO vs Entity Objects with comparison table
- Rules to be followed while creating POCOs - 4 important rules
- How to load related POCO entities - loading patterns and their differences in their usage with examples
- What is Change tracking in POCOs, ways of tracking
- Snapshot change tracking with DetectChanges() method
- Change tracking with proxies, How to create proxies?
- Instantiate POCO classes using ObjectContext.CreateObject method
- Using the DetectChanges() method to Fix-up Relationship in poco entities
- Entity Framework EntityKey object
- Retrieving a single entity with GetObjectByKey method of ObjectContext using EntityKey
- How to create an EntityKey in Entity Framework
- How to change the state of an entity using ChangeObjectState method of ObjectStateManager
- ChangeState method of ObjectStateEntry class
- Update an entity in a disconnected scenario using ApplyCurrentValues method
- Using ApplyOriginalValues method
- ObjectStateEntry class
- Entity state in Entity Framework - what, how, why?
- AcceptAllChanges and SaveChanges methods in Entity Framework
Azure Q & A
Azure Platform
Grid-View
GridView CommandField example
Details-View
GridView and DetailsView Master/Detail page using SqlDataSource control
POCO
POCO overview and advantages - POCO class, Entity Framework in Enterprise Applications
Entity Framework
Query entity data model using linq to entities
Array List
Difference between arraylist and list collection
Web Services
How to create a Web service using Visual Studio.net
Form-View
FormView DataBound Event
Object Oriented Programming
Calling base class constructor in C#
Linq
Convert a sequence to a generic list using ToList()method
Project Ideas
Project ideas for students
AccountingSoftware
Accounting Software
MVC
Creating an ASP.Net MVC 3 application
.Net
Using assemblies in .net applications
ASP .Net
How to implement form validation using ASP.Net 2.0 Validation Controls
VB .Net
Constructors in Visual Basic.Net