Linq to SQL - 什么更好?

Sas*_*sha 5 c# sql sql-server performance linq-to-sql

db.Albums.FirstOrDefault(x => x.OrderId == orderId)
Run Code Online (Sandbox Code Playgroud)

要么

db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 9

我打算说服你:

  • 您提出的两种方法可以提供相同的性能.
  • 您应该首选至少两个与性能无关的原因==.
  • 您可以对代码进行另一项单独的改进,以减少出错的可能性.

要查看性能是否相同,请查看每种情况下生成的SQL.此测试程序向您展示如何查看生成的SQL:

int orderId = 4;
TextWriter textWriter = new StringWriter();
using (var dc = new DataClasses1DataContext())
{
    dc.Log = textWriter;
    Order o1 = dc.Orders.FirstOrDefault(x => x.OrderId == orderId);
    Order o2 = dc.Orders.FirstOrDefault(x => x.OrderId.Equals(orderId));
}
string log = textWriter.ToString();
Run Code Online (Sandbox Code Playgroud)

在每种情况下发送的SQL都是相同的,您可以通过检查日志看到:

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description]
FROM [dbo].[Order] AS [t0]
WHERE [t0].[OrderId] = @p0

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description]
FROM [dbo].[Order] AS [t0]
WHERE [t0].[OrderId] = @p0
Run Code Online (Sandbox Code Playgroud)

关于是否使用==Equals,首先我建议使用==可读性.这是比较C#中两个整数的惯用方法.

其次,==如果给出不同(不兼容)类型的对象,则会出现编译时错误.我假设在你的情况下order有类型int,但让我们假设其他人写了这个代码并且意外地发生了一个错误,其中order是一个类型的变量Order而不是一个int.现在让我们比较每种情况会发生什么:

Order order = new Order { OrderId = 4 };

x.OrderId.Equals(order)  // This compiles, but you get an exception at runtime:
                         // Could not format node 'Value' for execution as SQL.

x.OrderId == order       // Compile error: Operator '==' cannot be applied to
                         // operands of type 'int' and 'Order'
Run Code Online (Sandbox Code Playgroud)

获得编译时错误比运行时错误更好,所以==在这种情况下更喜欢使用.

最后,如果您只希望使用一个结果,SingleOrDefault而不是FirstOrDefault因为前者将抛出异常,如果找到两个匹配的对象而不是仅返回第一个.这种额外的检查会花费很少的性能,但同样可以让您更早地发现错误.如果性能对您来说是一个关键问题,那么您应该考虑立即从数据库中提取多个对象,而不是一次从一个对象中提取多个对象,而不是删除这些安全检查.

总而言之,我建议你使用这个:

Album album = db.Albums.SingleOrDefault(x => x.OrderId == orderId);
Run Code Online (Sandbox Code Playgroud)

  • 好点.Equals()对类型过于宽容! (3认同)

Dav*_*kle 7

从性能角度来看,它们都是等价的.我倾向于选择== over .Equals()来提高可读性,但L2S的优点在于你可以使用任何一种,具体取决于你拥有的对象类型.

(我假设你的第二个声明在orderId上,而不是订单对象)