Linq to SQL - что лучше? - PullRequest
       29

Linq to SQL - что лучше?

5 голосов
/ 13 мая 2010
db.Albums.FirstOrDefault(x => x.OrderId == orderId)

или

db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))

Ответы [ 4 ]

9 голосов
/ 13 мая 2010

Я собираюсь убедить вас в том, что:

  • Два предложенных вами метода дают одинаковую производительность.
  • Есть как минимум две причины, не связанные с производительностью, которые вы должны предпочесть ==.
  • Существует еще одно отдельное улучшение, которое вы можете внести в свой код, чтобы уменьшить вероятность ошибок.

Чтобы увидеть, что производительность будет одинаковой, посмотрите на 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();

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

Что касается использования == или 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'

Лучше получать ошибки времени компиляции, чем ошибки времени выполнения, поэтому в этом случае предпочтительнее использовать ==.

Наконец, если вы ожидаете только одного результата, вы должны предпочесть использовать SingleOrDefault вместо FirstOrDefault, так как первый вызовет исключение, если найдены два соответствующих объекта вместо простого возврата первого. Эта дополнительная проверка будет стоить совсем немного производительности, но, опять же, позволит вам обнаруживать ошибки раньше. Если производительность является для вас критической проблемой, вместо удаления этих проверок безопасности вам следует рассмотреть возможность извлечения нескольких объектов из базы данных одновременно, а не одного объекта за раз.

Итак, в заключение, я рекомендую вам использовать это:

Album album = db.Albums.SingleOrDefault(x => x.OrderId == orderId);
7 голосов
/ 13 мая 2010

Они оба будут эквивалентны с точки зрения производительности. Я обычно предпочитаю ==, а не .Equals () для удобства чтения, но прелесть L2S в том, что вы можете использовать любой из них, в зависимости от типа объекта, который у вас есть.

(и я предполагаю, что ваш второй оператор находится на orderId, а не на объекте заказа)

1 голос
/ 13 мая 2010

В большинстве случаев вы должны получить тот же результат. Однако есть разница.

Использование оператора Equals определяет, являются ли два экземпляра объекта одинаковыми. Оператор == определяет, имеют ли два объекта одинаковое значение.

В этом случае я использую оператор ==, поэтому он более читабелен.

0 голосов
/ 13 мая 2010

Это почти то же самое. Если вы хотите проверить только значение, используйте

==

Если вы хотите проверить значение, а также, если они одинаковые экземпляры или не использовать

Равно

Но в обоих случаях полученное время практически одинаково.

...