db.Albums.FirstOrDefault(x => x.OrderId == orderId)
db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))
db.Albums.FirstOrDefault(x => x.OrderId == orderId)
db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))
Они оба будут эквивалентны с точки зрения производительности. Я предпочитаю использовать более .Equals() для удобочитаемости, но красота L2S заключается в том, что вы можете использовать любой из них, в зависимости от того, какой тип объекта у вас есть.
(И я предполагаю, что ваше второе утверждение находится на OrderId, а не объект заказа)
Я буду пытаться убедить вас в том, что:
==
.Чтобы увидеть, что производительность будет такой же, посмотрите на 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);
Я имею в виду, что порядок имеет тип int – Sasha
Хорошая точка .Equals() слишком разрешительная с типами! –
+1 Отличный ответ Марк! –
В большинстве случаев вы должны получить тот же результат. Однако есть разница.
Использование оператора Equals
определяет, являются ли два экземпляра объекта одинаковыми. Оператор ==
определяет, имеют ли два объекта одинаковое значение.
В этом случае я использую оператор ==
, поэтому он более читабельен.
+1 Хорошая точка. Если OrderId в БД имеет значение NULL, будет ли этот L2S перевести на 'x.Order == null'? Если это так, вызов '.Equals' завершится неудачно, так как в левой части нет действительного объекта. –
'Int32',' Guid' и все другие типы значений/примитивы имеют перегрузки 'Equals', которые принимают аргументы одного типа. Единственный экземпляр, когда это приведет к другому результату, - это аргумент 'orderId' на самом деле другого типа из свойства' Order.OrderId'. – Aaronaught
Это неправильно: метод Equals отмечен как виртуальный объект System.Object и может быть переопределен. Он должен делать то же самое, что и ==. –
Это почти то же самое. Если вы хотите проверить только значение, то вы должны использовать
==
Если вы хотите проверить значение, а также, если они одни и те же случаи, или не использовать
Equals
Но в обоих случаях результирующее время почти такое же.
'Equals' не означает ссылки на равенство. Он * может * выполнять контрольную проверку, когда аргументы являются и ссылочными типами, но в основном это совпадает с '=='. Если вам требуется ссылочное равенство, вы используете метод 'object.ReferenceEquals'. – Aaronaught
Я не делал C# годами, но разве это не автообъект, а вещь L2S? Или '' '' зависит от экземпляра под рукой? –
@yar: ничто не помещается в коробку, это дерево выражений, которое было посещено и преобразовано в SQL-запрос. – Aaronaught
@ Я не знаю, да, я вижу, что теперь я хотел бы взглянуть на код немного осторожно :) В то же время мне придется читать на деревьях выражений, потому что я думал, что «param» будет оценен прежде чем FirstOrDefault даже получит его. Видимо, это неправильно. –