Skip to content

In LINQ, Don’t Use Count() When You Mean Any()

If you have a list, array, or query in a C#/LINQ application and need to check and see if the list is empty, the correct way to do this is to use the Any() extension method:

if (q.Any())
{

Similarly, you can check to see if any elements in the list meet a certain condition:

if (q.Any(i => i.IsSpecial))
{

If the query provider is something like LINQ to Entities, this will be translated into fairly efficient SQL using EXISTS.

For some reason, I see a lot of people write this code using the Count() extension method instead (maybe they don’t know about Any()?), like this:

if (q.Count() > 0)
{

This is wrong for two reasons:

  • It’s imperative instead of expressive. Using Any() tells the query provider, "Please determine if the list is non-empty using the most efficient way you can." Using Count() > 0 tells the query provider, "Please do exactly what I tell you, regardless of what I really need." Because LINQ is intended to support a variety of query providers, it is important to be expressive instead of imperative, and to let the provider specialize the implementation.
  • Because we don’t actually care about the exact count of items in the list, only that it is greater than zero, using the Count() function can cause the provider to do considerably more work than necessary. Consider a linked list, or a SQL-based provider.

{ 5 } Comments

  1. Olaf Monien | April 22, 2010 at 1:16 am | Permalink

    Not using Count() if you don’t actual need the exact number, is very important as you lined out - agreed.

    "It’s imperative instead of expressive." is itself not a reason against using Count() imho, as this is very simplistic example only. There are real world situations, where you have to count or - more abstract - where you have to compare two values - even in expressive LINQs

    Response: If you actually need an exact count and are prepared to pay the performance cost of getting it, then by all means feel free to use .Count(). My point regarding expressivity is that when what you really need is .Any(), then you probably don’t need an exact count. FWIW, people make this same mistake in SQL all the time, and it’s wrong there for the same reasons it’s wrong in LINQ.

  2. Aaron Murray | November 30, 2011 at 12:53 pm | Permalink

    Agreed - this is a great post for anyone who is concerned about the performance of generated SQL using LINQ.

  3. Ray Akkanson | December 8, 2011 at 8:37 pm | Permalink

    Can we use ‘Any’ for null objects?

    Thanks
    Ray Akkanson

  4. Ray Akkanson | March 9, 2012 at 10:54 pm | Permalink

    Thanks. This is very useful information.

    Ray Akkanson

  5. Robert Fryca | May 13, 2013 at 6:01 am | Permalink

    Compare sql generated by EF 5.0.

    Count()
    ———————————————————————————————-
    SELECT
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT
    COUNT(1) AS [A1]
    FROM [dbo].[Members] AS [Extent1]
    WHERE [Extent1].[Uguid] = @p__linq__0
    ———————————————————————————————-

    Any()
    ———————————————————————————————-
    SELECT
    CASE WHEN ( EXISTS (SELECT 1 AS [C1] FROM [dbo].[Members] AS [Extent1] WHERE [Extent1].[Uguid] = @p__linq__0)) THEN cast(1 as bit)
    WHEN ( NOT EXISTS (SELECT 1 AS [C1] FROM [dbo].[Members] AS [Extent2] WHERE [Extent2].[Uguid] = @p__linq__0)) THEN cast(0 as bit) END AS [C1]
    FROM ( SELECT 1 AS X )
    ———————————————————————————————-

{ 1 } Trackback

  1. [...] استفاده از Any به جای Count وقتی منظورتون همون Any است. [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 713 access attempts in the last 7 days.

Close