Зачем использовать "select new" в LINQ
Я очень новичок в LINQ to SQL, поэтому, пожалуйста, простите меня, если это вопрос непрофессионала.
Во многих местах я вижу, что мы используем ключевое слово "select new"
в запросе.
Например,
var orders = from o in db.Orders select new {
o.OrderID,
o.CustomerID,
o.EmployeeID,
o.ShippedDate
}
Почему бы нам просто не удалить новый и просто использовать "select o"
var orders = from o in db.Orders select o;
То, что я могу отличить, - это разница в производительности в терминах скорости, то есть второй запрос займет больше времени, чем первый.
Существуют ли какие-либо другие "различия" или "лучше использовать" концепции между ними?
Ответы
Ответ 1
С ключевым словом new
они создают анонимный объект только с этими четырьмя полями. Возможно, у ордеров 1000 полей, и им нужно только 4 поля.
Если вы делаете это в LINQ-to-SQL или Entity Framework (или других подобных ORM), SELECT
, который он будет создавать и отправлять на SQL Server, будут загружать только эти 4 поля (обратите внимание, что NHibernate не точно поддерживает прогнозы на уровне db. Когда вы загружаете объект, вы должны его полностью загрузить). Меньше данных, передаваемых по сети И есть небольшая вероятность того, что эти данные содержатся в индексе (загрузка данных из индекса обычно быстрее, чем загрузка из таблицы, поскольку таблица может иметь 1000 полей, в то время как индекс может содержать ТОЧНО те 4 поля).
Операция выбора только некоторых столбцов в терминологии SQL называется PROJECTION
.
Конкретный случай: скажем, вы создаете файловую систему поверх SQL. Поля:
- filename VARCHAR (100)
- данные BLOB
Теперь вы хотите прочитать список файлов. Простой SELECT filename FROM files
в SQL. Было бы бесполезно загружать data
для каждого файла, в то время как вам нужен только filename
. И помните, что часть data
может "весить" мегабайты, а часть filename
- до 100 символов.
После прочтения того, насколько "забава" использует new
с анонимными объектами, не забудьте прочитать, что написала @pleun
, и помните: ORM - это как айсберги: 7/8 их работы скрыты под поверхностью и готовы укусить вас.
Ответ 2
Ответ дан хорошо, однако я хотел бы добавить еще один аспект.
Потому что, используя select new { }
, вы отсоединяетесь от datacontext и заставляете вас потерять механизм отслеживания изменений Linq-to-Sql.
Таким образом, для отображения только данных это нормально и приведет к увеличению производительности.
НО, если вы хотите делать обновления, это не гонка.
Ответ 3
В select new
мы создаем новый анонимный тип с только теми свойствами, которые вам нужны. Все они получат имена и значения свойств из соответствующих ордеров. Это полезно, когда вы не хотите отбрасывать все свойства из источника. Некоторые могут быть большими (думаю varchar(max)
, binary
или xml
типы данных), и мы можем исключить их из нашего запроса.
Если вы были в select o
, вы бы выбрали Order
со всеми его свойствами и поведением.