Avoiding Roundtrip with Load in Entity Framework

If you have queries in your classes that you are reusing across your entire business layer, it becomes really hard sometimes to do eager loading of certain child entities on those queries. For example, if you have method that runs a complex linq to entity query to return you a collection of Orders. What if in certain scenarios of your application, you would like to retrieve Customers for those orders as well. Either you can create another method just like your previous method which has that complex query duplicated but along with that query you support the concept of eager loading of Customer entities as well.  Other option you have is if the orders returned from the method are not too many and in manageable size, than you may end up wanting to reuse the method and incur the cost of lazy loading of the Customers. Below is an example that shows how I would lazy load Customers for an Order.

image

image

  In the above code, I have a method called GetOrdersBycity which retrieves the Orders for the city of London. Just to keep you in loop, the total orders in the database for the city of London is 33. Since we also want to print the CustomerId for those orders, I am explicitly calling CustomerReference.Load to load the customer for that order. We need to call load on the customer reference otherwise we will end up with a null reference because entity framework does not load anything automatically from the database.  Since there are 33 orders that meet the criteria we end up making 33 database calls to retrieve customers for those orders. Now the question is, do we really think that entity framework should have made 33 database calls. Personally I think, entity framework, should make database calls equal to the number of unique customers for those orders. Here is the reason why. Since we already have orders in our hand and each order knows what CustomerId it belongs to, I think entity framework should look into its object tracking service to see if its tracking this object. If the object is found in the tracking repository, it should not make an extra database call to retrieve the same customer that was already being tracked in the tracking service. But the reality of the matter is, if you turn on your profiler, you would see 33 database calls being made.

The question is how can we prevent the entity framework from making extra round trips to the database?  Entity framework exposes an additional property called IsLoaded which you can check to see if the reference to the object is already loaded. If the object is already from a previous database query, than do not call load on the object again. Below is an example that shows to achieve that.

image

image

In the above code, I am checking the IsLoaded property to check if customer reference is already loaded. Only when the customer is not loaded I call Load. By applying a simple tweak in my query, I end up only making 5 database calls which means that I had 5 unique customers for all 33 orders. With simple checking we managed to improve our loading experience of related entitles by orders of magnitude.

2 Comments

Comments have been disabled for this content.