Optimizing queries that retrieve a single element in ASP.NET

Leave a Comment

The easiest way to retrieve a single element is to search its key and use the LINQ to Entities First method. Even if the object has already been queried once and is in the state manager, Entity Framework reissues the query each time the First method is used. Data already exists in the state manager; because Entity Framework reuses the state manager entity, it discards the data from the database. This process is a waste of resources that you can avoid.

A GetCustomerById method is called frequently in your code. This method uses the LINQ to Entities First method to access the customer. You have to optimize the performance of this method to avoid a query against the database.

Even this problem has a relatively simple solution. The ObjectContext class has a GetObjectByKey method that lets you retrieve a single object by its key. Its peculiarity is that before going to the database, this method asks the state manager if an entity of that type with the given key is already in memory. If this query is true, the method returns the in-memory entity without going to the database; otherwise, it queries the database and puts the entity in the state manager.

A query looks for an entity by its key. If the entity is in memory, it’s returned immediately. If it’s not in memory, the GetObjectByKey method retrieves it from the database and puts it in memory.

Invoking the GetObjectByKey method is a bit cumbersome. You have to create an EntityKey instance (a class that the state manager uses to represent the key of an entity) and pass in the entity set, the name of the primary key, and its value. After that, you pass the EntityKey object to the GetObjectByKey method, which returns an object instance that you have to manually cast to the real type. The following listing transforms this scenario into code.
var c = (Customer)ctx.GetObjectByKey(
new EntityKey("NorthwindEntities.Customers", "CustomerID", "ALFKI"));
var c2 = (Customer)ctx.GetObjectByKey(
new EntityKey("NorthwindEntities.Customers", "CustomerID", "ALFKI"));

The first statement retrieves the entity from the database, whereas the second statement retrieves the entity from the state manager, sparing a database round trip.

If the object doesn’t exist on the database, the GetObjectByKey method throws an exception. To keep that from happening, you can use the TryGetObjectByKey method. We encourage the use of GetObjectByKey and TryGetObjectByKey as another little precaution that, performance-wise, really makes the difference.

0 comments:

Post a Comment