I have been using the Find(id)
extension method with collections in Entity Framework 5. However, many of the examples I see use Where(s => s.Id == 1)
, to which I added FirstOrDefault()
to get the object instead of a collection. Is this a style difference, or is there a functional reason for the apparent .Where() preference?
The key thing to notice here is that FirstOrDefault is called on Enumerable whereas Find is called as a method on the source list. So it's iterating over an array of items which makes sense, since a list is a wrapper on an array.
The Where and FirstOrDefault methods are applicable against multiple kinds of sequences, including List<T> , T[] , Collection<T> , etc. Any sequence that implements IEnumerable<T> can use these methods. Find is available only for the List<T> .
When you want a default value is returned if the result set contains no record, use SingleOrDefault. When you always want one record no matter what the result set contains, use First or FirstOrDefault. When you want a default value if the result set contains no record, use FirstOrDefault.
FirstOrDefault() - Same as First(), but not thrown any exception or return null when there is no result. Single() asserts that one and only one element exists in the sequence. First() simply gives you the first one.
Find() has a fundamental difference to Where(), Single(), First() etc. in that it will first search for the object in memory and only hit the database if the object has not already been loaded. Thus try to use Find() where possible as it offers possible speed benefits of loading from memory. Find() only works with the primary key and doesn't support lambdas so it is not very flexible.
Where() is typically used to get a listing of objects. To retrieve a single object I normally use either Single(), SingleorDefault(), First(), FirstorDefault().
Single() and SingleOrDefault() differ from First() and FirstOrDefault() as they ensure that a maximum of one object can satisfy the criteria which helps ensure the integrity of the data in the database. They 'Single' clauses do this by selecting 'TOP 2' in the SQL query and then throwing an exception if two entities are returned.
Note that you should not chain these to the end of the Where() clause.
So instead of
.Where(s => s.Id == 1).FirstOrDefault();
use:
.FirstOrDefault(s => s.Id == 1);
I wrote a blog post to fully explore this issue : http://judeokelly.com/primer-on-selecting-data-using-entity-framework/
If performance matters, as per http://wp.secretnest.info/archives/2991 , .Where(...).FirstOrDefault() is much faster than FirstOrDefault(...). Of course a List Find() might again be much faster than the previous.
So contrary to the accepted answer, you should not avoid Where(...).FirstOrDefault()!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With