LINQ: Разница между «Выбрать c» и «Выбрать новый (c ...» - PullRequest
5 голосов
/ 10 августа 2009

В чем разница между этими двумя утверждениями:

 var result = from c in context.CustomerEntities
 join p in context.ProjectEntities on c.Pk equals p.CustomerPk
 where p.Entered > DateTime.Now.AddDays(-15)
 select c; 

и

 var result = from c in context.CustomerEntities
 join p in context.ProjectEntities on c.Pk equals p.CustomerPk
 where p.Entered > DateTime.Now.AddDays(-15)
 select new (c.Company, c.Entered, c.pk);

Есть ли какие-либо проблемы с производительностью в этих заявлениях. (Для простоты c содержит только эти 3 столбца.)

Спасибо.

Ответы [ 4 ]

10 голосов
/ 10 августа 2009

В чем разница между этими двумя утверждениями

Первый возвращает отфильтрованную последовательность исходного / полного исходного объекта; вторая по-прежнему выполняет фильтрацию, но возвращает последовательность анонимного типа с просто этими тремя свойствами.

Есть ли какие-либо проблемы с производительностью в этих заявлениях

Производительность зависит от серверной части. Если это LINQ-to-Objects, то с помощью new {...} вы создаете дополнительные объекты (анонимные типы) для каждой записи, поэтому могут быть очень небольшие накладные расходы. Однако, если это LINQ-to-SQL и т. Д. (Серверная часть базы данных), это может быть огромным преимуществом . Построитель запросов проверит, какие столбцы нужны, и выберет только три в вашем anon-типе; если у вас есть (например) BLOB (или просто длинный varchar) в ваших данных, которые вам не нужны, это может быть огромным преимуществом.

Дополнительные примечания: вы не можете включать анонимные типы в сигнатуру метода, поэтому вам может потребоваться объявить для этого собственный тип DTO:

return new CustomerDto { Company = c.Company, Entered = c.Entered, PK = c.pk};
...
public class CustomerDto { ... }
2 голосов
/ 19 августа 2009

Я провел несколько тестов (используя секундомер). Ни в одном случае анонимные типы не были быстрее, в Linq-to-SQL (против SQL Server), Linq-to-Entities (против MySQL) и Linq-to-Objects (против List). На самом деле, обычно это было медленнее, в зависимости от того, сколько столбцов вы выбрали.

Один из моих результатов: Я выполнял каждый запрос 5000 раз для таблицы из 5 столбцов, заполненной 400 строками с помощью Linq-to-Entities.

анонимный объект (выбор 1 столбца): 17314ms

анонимный объект (выбор 5 столбцов): 19193мс

исходный объект: 16055мс

В любом случае, лучший способ выяснить это - проверить это самостоятельно (на написание хорошего поста уходит время).

2 голосов
/ 10 августа 2009

Основное отличие состоит в том, что первый пример возвращает ссылки на существующие экземпляры, а второй пример создает новые экземпляры анонимного типа. Я был бы более обеспокоен этой проблемой, чем любые возможные проблемы с производительностью.

1 голос
/ 10 августа 2009

В случае сомнений, профиль.

Но да, я думаю, что это приводит к снижению производительности. Если вы сделаете select c, то коллекция будет содержать ссылки на оригинальные предметы. Если вы делаете select new { ... }, то C # создает для вас анонимный тип, создает новые экземпляры этого типа и заполняет их данными. Звучит определенно медленнее для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...