Entity Framework – Find() vs. FirstOrDefault()

Imagine you need to find an entity using your database context filtering by primary key.
There are two main options:
a) .FirstOrDefault()
b) .Find()

The latter one is the better one.
FirstOrDefault() method always executes a query on the database.
Find() method is more complicated. At first it checks if required entity is already loaded into in memory database context. If it is – the result is returned without hitting the database. If not query on the database is executed.

See example below. At first we select five rows from the database. Then we use FirstOrDefault – ‘query1’ is sent to the database, despite the fact that the entity we are looking for already exists in context. Then we try to get the same entity using Find method. ‘Query2’ is not sent to the database, because this entity already exists in our context. The last ‘query3’ uses Find method, but required entity is not existing in our context yet, therefore query is sent to the database.

private static void FindVsFirstOrDefault()
{
	using (var context = new TSQL2012Entities())
	{
		context.Database.Log = (string msg) => { Console.WriteLine(msg); };
		var people = context.Employees.Where(p => p.empid <= 5).ToList();

		//asks database for a person using PK
		Console.WriteLine("FirstOrDefault");
		var query1 = context.Employees.FirstOrDefault(p => p.empid == 1);

		//asks first the database context (in memory). Entity is already loaded, so it returns it without querying the database.
		Console.WriteLine("Find 1");
		var query2 = context.Employees.Find(1);

		//asks first the database context (in memory). Entity is not loaded yet, so it asks the database.
		Console.WriteLine("Find 6");
		var query3 = context.Employees.Find(6);

	}
}

Notice that Find() method can operate only when primary key is passed as a parameter.

1 thought on “Entity Framework – Find() vs. FirstOrDefault()

Leave a comment