Почему LINQ to SQL генерирует несколько запросов на выборку?

Я использую LINQ2SQL. Я только что заметил (в SQL Profiler), что LINQ генерирует несколько операторов выбора для приведенного ниже LINQ.

var tableData = dataContext.ИмяТаблицы.ToList();

Профилировщик SQL дважды показывает приведенные ниже операторы DML.

Выберите columnNames из TableName.

Что является причиной этого?


person Miral    schedule 31.01.2011    source источник
comment
@Miral: я позволил себе отредактировать ваш вопрос в реальный вопрос, а также отредактировал теги. Пожалуйста, просмотрите его и измените, если я что-то неправильно понял.   -  person Fredrik Mörk    schedule 31.01.2011
comment
Вы уверены, что он действительно выполнил запрос дважды? В первый раз могла быть просто проверка подготовки или синтаксиса (SET PARSEONLY)   -  person Blorgbeard    schedule 31.01.2011
comment
Я проверял несколько раз, да, он дважды генерирует оператор выбора   -  person Miral    schedule 31.01.2011
comment
Спасибо за изменение вопроса и тегов   -  person Miral    schedule 31.01.2011
comment
Делает ли он это для очень простого консольного исполняемого файла, который просто делает что-то одно? (создайте контекст данных, получите данные в список)   -  person Marc Gravell    schedule 31.01.2011
comment
@Ryk - я вообще не уверен, что это правда; У меня есть (почти) полный контроль над моим кодом LINQ, что и когда выполняется. Однако без полной репродукции это все равно невозможно узнать в данном случае.   -  person Marc Gravell    schedule 02.03.2011
comment
@Marc G - хе-хе, почти. Если у вас есть транзакционная система, «почти» равносильно нулю. Но, как я уже сказал, LINQ имеет свое место, и я не против этого, я не буду тянуть прицеп с грузовиком, и я не буду тянуть прицеп с моей машиной, получайте мой дрифт.... Лошади на курсы.   -  person Ryk    schedule 02.03.2011
comment
@Ryk - а когда LINQ не подходит, я просто перехожу на TSQL через Execute*...   -  person Marc Gravell    schedule 02.03.2011
comment
@Marc G - именно моя точка зрения. Если цель подходит, делайте это. Самое опасное, что может сделать любой разработчик, — это использовать одну методологию для выполнения «X», а все остальные сценарии должны соответствовать его методологии. Я говорю нет, исследуйте, используйте все и смотрите, как каждая технология и фреймворк подходят для каждой ситуации, а затем начинайте использовать правильный фреймворк/технологию в тех местах, где вы считаете, что они работают лучше всего!   -  person Ryk    schedule 03.03.2011


Ответы (2)


Запрос в том виде, в котором он представлен, будет выполнять ровно один оператор выбора. Интересно, не кроется ли здесь проблема в переносе вопроса на простой пример. Скорее всего, в фактическом коде данные не помещаются в список. Такие методы, как .Where(), только создают запрос — данные не загружаются в список, поэтому следующие два запроса:

var tableData = dataContext.TableName.Where(row => row.Foo == bar);
foreach(var items in tableData) {...}
foreach(var items in tableData) {...}

Добавление .ToList() заставит его буферизоваться в памяти в одном запросе TSQL; последующее перечисление по списку будет выполняться в памяти (LINQ-to-Objects).

Конечно, вы можете довольно просто профилировать то, что выполняет LINQ-to-SQL:

dataContext.Log = Console.Out; // or any other text-writer
person Marc Gravell    schedule 31.01.2011
comment
Я думаю, что это то, что он делает на самом деле. Его проблема, по-видимому, заключается в том, что метод .ToList() дважды вызывает базу данных. - person vtortola; 31.01.2011
comment
@vtortola и когда я увижу репродукцию, я поверю, что - person Marc Gravell; 31.01.2011

SQL Server Profiler по умолчанию подписывается на следующие события;

Audit Login
Audit Logout
Existing Connection
RPC:Completed
SQL:BatchCompleted
SQL:BatchStarting

Если вы запустите профилировщик с этими событиями по умолчанию, вы увидите, что каждый пакетный оператор повторяется 2 раза только из-за событий SQL:BatchStarting и SQL:BatchCompleted. Это распространенное заблуждение, которое стоит проверить.

person orka    schedule 26.02.2011