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
}
考虑上面的例子,我列出了30岁以上的员工。
方法1和方法2有什么区别? 你更喜欢哪一个?为什么?
答案 0 :(得分:14)
我更倾向于使用第二种方法来实现可读性。如果你看一下生成的sql代码,它就是一样的。
方法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
方法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
在一天结束时,更多的是个人偏好。对于不习惯linq的人来说,在计数之前使用where子句可能更具可读性。
修改1
旁注。是的,生成sql是一样的。但IL代码在一个地方是不同的。在应用计数和地点时。
方法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
方法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
修改2
解决评论。是的,我会检查执行时间,看看有什么意义。我仍然相信第二个会更快。但你必须检查。如果它是代码的性能关键部分。从数据库方面,我会检查查询的执行计划。它可能会在Age列上添加索引。
编辑3
您还可以测量执行命令所需的时间。这是使用Stopwatch
类的简短演示:
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);
在我的测试中,TblEmployees为空。我得到了这个结果:
00:00:00.0019229
00:00:00.0007023
答案 1 :(得分:1)
性能没有差异。这只是关于代码的可读性。
我创建了一个表并在LINQPad中运行了两个查询。以下是输出:
方法1的SQL:
-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
WHERE [t0].[Type] = @p0
执行时间:00:00.279
方法2的SQL:
-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT COUNT(*) AS [value]
FROM [Employees] AS [t0]
WHERE [t0].[Type] = @p0
执行时间:00:00.275
在这里,您可以看到LINQ生成的SQL与执行时间的微小差异没有区别。