Entity Framework Tips and Tricks: Use GetObjectByKey When Querying a Single Entity
Sep 7, 2011 • C#I’ve been using Entity Framework a lot lately and it makes data access really nice. It’s fairly simple to use and maps all your tables to a .NET object model. However, just like any other library, it can be misused and have it’s own issues. I’ve been figuring some things out as I’ve been using it, so I thought I’d share a few tip and tricks that I’ve learned. Here’s the first one:
Use “GetObjectByKey” when Querying for a Single data entity
Take the following query:
var person = (from p in context.Persons
where p.ID == id
select p).FirstOrDefault();
This query will find all the Person
entities that have a specific ID
and then return the first one or null if it doesn’t exist. This query is perfectly valid and will operate as expected. However, if you were to call that query multiple times, it will hit the database every time it’s called and never cache the entity. In order to “cache” the entity for future calls you would need to keep the person
variable around for any future use.
Now, take the following code:
var keyValues = new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("ID", id)
};
var key = new EntityKey("DataEntities.Persons", keyValues);
var person = (Person)context.GetObjectByKey(key);
This code uses the GetObjectByKey
method to return the same Person
entity as the above query. However, there is one critical difference. This code will check the cache before hitting the database to see if the entity has already been loaded into memory using Entity Framework.
Basically, the first call to GetObjectByKey
will query the database, and any subsequent calls for the same entity will just return it from the cache. You must remember when using this method that it wont refresh the data from the database if it exists in the cache, so in certain circumstances, it may still be better to perform a query to make sure the data returned is the latest and not stale.
The GetObjectByKey
method will throw an ObjectNotFoundException if the requested object cannot be found. To avoid handling the exception, you can alternatively use the TryGetObjectByKey
method instead.
Here’s a generic method and it’s sample usage that I’ve created to make using TryGetObjectKey
a little simpler:
static T GetEntityByID<T>(string entitySetName, Guid id)
where T: class
{
object val = null;
// Create the EntityKey
var keyValues = new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("ID", id)
};
var key = new EntityKey(
string.Format("DataEntities.{0}", entitySetName),
keyValues
);
// Try to get the Object using the Key
context.TryGetObjectByKey(key, out val);
// cast the object as T
// this will return Null if the object doesn't exist
return val as T;
}
// Example usage of the method
var person = GetEntityByID<Person>("Persons", id);
You could even go a step further and wrap the above GetEntityByID<Person>()
call into a method like GetPersonByID(Guid id)
to make it easier to use.
Related Posts
-
C#: Case-Insensitive String Contains Best Practices
18 Oct 2024 -
C#: Read Text and JSON File Contents into Variable in Memory
18 Jun 2024 -
How to Cast an Int to an Enum in C#
17 Jun 2024