views:

2612

answers:

6

Consider the IEnumerable extension methods SingleOrDefault() and FirstOrDefault()

MSDN documents that SingleOrDefault:

Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.

whereas FirstOrDefault from MSDN (presumably when using an OrderBy() or OrderByDescending() or none at all),

Returns the first element of a sequence

Consider a handful of example queries, it's not always clear when to use these two methods:

var someCust = db.Customers
.SingleOrDefault(c=>c.ID == 5); //unlikely(?) to be more than one, but technically COULD BE

var bobbyCust = db.Customers
.FirstOrDefault(c=>c.FirstName == "Bobby"); //clearly could be one or many, so use First?

var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or does it matter?

Question

What conventions do you follow or suggest when deciding to use SingleOrDefault() and FirstOrDefault() in your LINQ queries?

+4  A: 

FirstOrDefault is most probably faster,because SingleOrDefault needs to check if there is only one element.

I would say, use FirstOrDefault if you don't care how many items there are, use SingleOrDefault to make sure that you select a unique item.

Stefan Steinegger
+15  A: 

Whenever you use SingleOrDefault, you clearly state that the query should result in at most a single result. On the other hand, when FirstOrDefault is used, the query can return any amount of results but you state that you only want the first one.

I personally find the semantics very different and using the appropriate one, depending on the expected results, improves readability.

Bryan Menard
+2  A: 

I use SingleOrDefault in situations where my logic dictates that the will be either zero or one results. If there are more, it's an error situation, which is helpful.

spender
+1  A: 

In your last example:

var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or doesn't matter?

Yes it does. If you try to use SingleOrDefault() and the query results in more than record you would get and exception. The only time you can safely use SingleOrDefault() is when you are expecting only 1 and only 1 result...

J.13.L
+3  A: 

In your cases, I would use the following:

select by ID==5: it's OK to use SingleOrDefault here, because you expect one [or none] entity, if you got more than one entity with ID 5, there's something wrong and definitely exception worthy.

when searching for people whose first name equals "Bobby", there can be more than one (quite possibly I would think), so you should neither use Single nor First, just select with the Where-operation (if "Bobby" returns too many entities, the user has to refine his search or pick one of the returned results)

the order by creation date should also be performed with a Where-operation (unlikely to have only one entity, sorting wouldn't be of much use ;) this however implies you want ALL entities sorted - if you want just ONE, use FirstOrDefault, Single would throw every time if you got more than one entity.

Olli
+1  A: 

SingleOrDefault: You're saying that "At most" there is one item matching the query or default FirstOrDefault: You're saying that there is "At least" one item matching the query or default

Say that out loud next time you need to choose and you shall likely choose wisely. :)

Steven
Thanks Steven! :)
p.campbell