using (DBEntities db = new DBEntities())
{
var employeeAgedAbove30 = db.Employees.Where(s => s.Age > 30).Count(); // Method 1
employeeAgedAbove30 = db.Employees.Count(s => s.Age > 30); // Method 2
}
Consider the above example where I take a list of employees aged above 30.
What is the difference between Method 1 and Method 2? Which one would you prefer and why?
COUNT(*) counts all rows in the result set (or group if using GROUP BY). COUNT(column_name) only counts those rows where column_name is NOT NULL. This may be slower in some situations even if there are no NULL values because the value has to be checked (unless the column is not nullable).
COUNT ( * ) counts all the rows in the target table whether they include nulls or not. COUNT ( expression ) computes the number of rows with non-NULL values in a specific column or expression. COUNT ( DISTINCT expression ) computes the number of distinct non-NULL values in a column or expression.
SQL SELECT COUNT with WHERE clauseSQL SELECT COUNT() can be clubbed with SQL WHERE clause. Using the WHERE clause, we have access to restrict the data to be fed to the COUNT() function and SELECT statement through a condition.
SQL Server COUNT() Function The COUNT() function returns the number of records returned by a select query. Note: NULL values are not counted.
I would prefer the second method for the readability. If you look at the generated sql code it is the same.
Method 1:
db.TblEmployees.Where (t =>t.Age>30).Count ()
SQL
-- Region Parameters
DECLARE @p0 Int = 30
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [tblEmployees] AS [t0]
WHERE [t0].[Age] > @p0
GO
Method 2:
db.TblEmployees.Count (t =>t.Age>30)
SQL
-- Region Parameters
DECLARE @p0 Int = 30
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [tblEmployees] AS [t0]
WHERE [t0].[Age] > @p0
At the end of the day it is more about personal preference. For someone not used to linq it might be more readable with a where clause before the count.
Edit 1
On the side note. Yes the generate sql is the same. But the IL code is different in one place. When applying the count and the where.
Method 1:
IL_0001: ldarg.0
IL_0002: stloc.0 // db
IL_0003: ldloc.0 // db
IL_0004: callvirt LINQPad.User.TypedDataContext.get_TblEmployees
IL_0009: ldtoken LINQPad.User.TblEmployees
IL_000E: call System.Type.GetTypeFromHandle
IL_0013: ldstr "t"
IL_0018: call System.Linq.Expressions.Expression.Parameter
IL_001D: stloc.1 // CS$0$0000
IL_001E: ldloc.1 // CS$0$0000
IL_001F: ldtoken LINQPad.User.TblEmployees.get_Age
IL_0024: call System.Reflection.MethodBase.GetMethodFromHandle
IL_0029: castclass System.Reflection.MethodInfo
IL_002E: call System.Linq.Expressions.Expression.Property
IL_0033: ldc.i4.s 1E
IL_0035: box System.Int32
IL_003A: ldtoken System.Int32
IL_003F: call System.Type.GetTypeFromHandle
IL_0044: call System.Linq.Expressions.Expression.Constant
IL_0049: ldtoken System.Nullable<System.Int32>
IL_004E: call System.Type.GetTypeFromHandle
IL_0053: call System.Linq.Expressions.Expression.Convert
IL_0058: call System.Linq.Expressions.Expression.GreaterThan
IL_005D: ldc.i4.1
IL_005E: newarr System.Linq.Expressions.ParameterExpression
IL_0063: stloc.2 // CS$0$0001
IL_0064: ldloc.2 // CS$0$0001
IL_0065: ldc.i4.0
IL_0066: ldloc.1 // CS$0$0000
IL_0067: stelem.ref
IL_0068: ldloc.2 // CS$0$0001
IL_0069: call System.Linq.Expressions.Expression.Lambda
IL_006E: call System.Linq.Queryable.Where
IL_0073: call System.Linq.Queryable.Count
Method 2:
IL_0001: ldarg.0
IL_0002: stloc.0 // db
IL_0003: ldloc.0 // db
IL_0004: callvirt LINQPad.User.TypedDataContext.get_TblEmployees
IL_0009: ldtoken LINQPad.User.TblEmployees
IL_000E: call System.Type.GetTypeFromHandle
IL_0013: ldstr "t"
IL_0018: call System.Linq.Expressions.Expression.Parameter
IL_001D: stloc.1 // CS$0$0000
IL_001E: ldloc.1 // CS$0$0000
IL_001F: ldtoken LINQPad.User.TblEmployees.get_Age
IL_0024: call System.Reflection.MethodBase.GetMethodFromHandle
IL_0029: castclass System.Reflection.MethodInfo
IL_002E: call System.Linq.Expressions.Expression.Property
IL_0033: ldc.i4.s 1E
IL_0035: box System.Int32
IL_003A: ldtoken System.Int32
IL_003F: call System.Type.GetTypeFromHandle
IL_0044: call System.Linq.Expressions.Expression.Constant
IL_0049: ldtoken System.Nullable<System.Int32>
IL_004E: call System.Type.GetTypeFromHandle
IL_0053: call System.Linq.Expressions.Expression.Convert
IL_0058: call System.Linq.Expressions.Expression.GreaterThan
IL_005D: ldc.i4.1
IL_005E: newarr System.Linq.Expressions.ParameterExpression
IL_0063: stloc.2 // CS$0$0001
IL_0064: ldloc.2 // CS$0$0001
IL_0065: ldc.i4.0
IL_0066: ldloc.1 // CS$0$0000
IL_0067: stelem.ref
IL_0068: ldloc.2 // CS$0$0001
IL_0069: call System.Linq.Expressions.Expression.Lambda
IL_006E: call System.Linq.Queryable.Count
Edit 2
To address the comment. Yes I would check the execution time and see what make sense. I still would believe that the second would be faster. But you have to check. If it is a performance critical part of your code. From the database side I would check the execution plan of the query. It might make sence to add a index on the Age column.
Edit 3
You could also measure the time it takes too execute the commands. This is a short demo using the Stopwatch
class:
var st=new Stopwatch();
st.Start();
db.TblEmployees.Where (t =>t.Age>30).Count ();
st.Stop();
Console.WriteLine(st.Elapsed);
st.Restart();
db.TblEmployees.Count (t =>t.Age>30);
st.Stop();
Console.WriteLine(st.Elapsed);
In my test with the TblEmployees empty. I get this result:
00:00:00.0019229
00:00:00.0007023
There is no difference in performance. It is just about readability of the code.
I created a table and run both query in LINQPad. Following are the output:
SQL for Method 1:
-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
WHERE [t0].[Type] = @p0
Execution time: 00:00.279
SQL for Method 2:
-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
WHERE [t0].[Type] = @p0
Execution time: 00:00.275
Here you can see there is no difference in SQL generated by LINQ and minor difference in execution time.
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