Зачем использовать «выбрать новый» в LINQ - PullRequest
17 голосов
/ 04 сентября 2011

Я очень новичок в LINQ to SQL, поэтому, пожалуйста, прости меня, если это непрофессиональный вопрос.

Я вижу во многих местах, что мы используем ключевое слово "select new" в запросе.Например,

var orders =  from o in db.Orders select new {
                o.OrderID,
                 o.CustomerID,
                 o.EmployeeID,
                 o.ShippedDate
           }

Почему бы нам просто не удалить select new и просто использовать "select o"

var orders =  from o in db.Orders select o;

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

Есть ли между ними какие-либо другие понятия "различия" или "лучше использовать"?

Ответы [ 3 ]

30 голосов
/ 04 сентября 2011

С помощью ключевого слова new они создают анонимный объект только с этими четырьмя полями. Возможно, у Orders есть 1000 полей, и им нужно всего 4 поля.

Если вы делаете это в LINQ-to-SQL или Entity Framework (или других подобных ORM), SELECT, который он создаст и отправит на SQL Server, загрузит только эти 4 поля (обратите внимание, что NHibernate не точно поддерживать проекции на уровне БД. Когда вы загружаете объект, вы должны загрузить его полностью). Меньше данных, передаваемых по сети И существует небольшая вероятность того, что эти данные содержатся в индексе (загрузка данных из индекса обычно быстрее, чем загрузка из таблицы, поскольку таблица может иметь 1000 полей, в то время как индекс может содержать ТОЧНО эти 4 поля).

Операция выбора только некоторых столбцов в терминологии SQL называется PROJECTION.

Конкретный случай: допустим, вы строите файловую систему поверх SQL. Поля:

  • имя файла VARCHAR (100)
  • данные BLOB

Теперь вы хотите прочитать список файлов. Простой SELECT filename FROM files в SQL. Было бы бесполезно загружать data для каждого файла, в то время как вам нужен только filename. И помните, что часть data может «весить» мегабайты, а часть filename может содержать до 100 символов.

Прочитав, сколько «забавы» использует new с анонимными объектами, не забудьте прочитать, что написано @pleun, и помните: ORM похожи на айсберги: 7/8 их работы скрыты под поверхностью и готовы чтобы откусить тебя назад.

14 голосов
/ 05 сентября 2011

Ответ дан хорошо, однако я хотел бы добавить еще один аспект.

Потому что, используя select new { }, вы отключаетесь от текста данных, и это приводит к потере механизма отслеживания изменений Linq-to-Sql.

Так что только для отображения данных это нормально и приведет к увеличению производительности.

НО, если вы хотите делать обновления, это не пойдет.

2 голосов
/ 04 сентября 2011

В select new мы создаем новый анонимный тип только с необходимыми вам свойствами.Все они получат имена и значения свойств из соответствующих заказов.Это полезно, когда вы не хотите извлекать все свойства из источника.Некоторые из них могут быть большими (например, varchar(max), binary или xml типы данных), и мы можем исключить их из нашего запроса.

Если бы вы набрали select o, то вы бывыбрать Order со всеми его свойствами и поведением.

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