2012-12-28 2 views
5

Я бегу в проблемы со следующим pseudoquery:Две подобные LINQ запросы, совершенно разные генерироваться SQL

var daily = from p in db.table1 
      group p by new 
      { 
       key1, 
       key2 
      } into g 
      join d in db.table2 
      on new { p.key1, p.key2 } equals { d.key1, d.key2 } 
      select new 
      { 
       col1 = g.Key.key1 
       col2 = g.Sum(a => a.column2) 
       col3 = d.column3 
      }; 

Он работает, но сгенерированный SQL заявление, что LINQ посылает SQL Server является абсурдным. Фактическая реализация следует аналогичной настройке, как указано выше, с 7 или более столбцами, каждая из которых имеет вычисление .Sum(). Сгенерированный SQL имеет где-то около 10-11 вложенных операторов SELECT без INNER JOIN и, конечно же, навсегда запускается.

Я проверил еще одну реализацию запроса:

var daily = from p in 
       (from p in db.table1 
       group p by new 
       { 
        key1, 
        key2 
       } into g 
       select new 
       { 
        col1 = g.Key.key1, 
        col2 = g.Sum(a => a.column2) 
       }) 
      join d in db.table2 
      on new { p.key1, p.key2 } equals new { d.key1, d.key2 } 
      select new 
      { 
       col1 = p.col1, 
       col2 = p.col2, 
       col3 = d.column3 
      }; 

Эта версия создает гораздо более разумный SQL с одной SUB-SELECT и INNER JOIN заявление (он также работает чуть мгновенно). Я ненавижу об этом, так это то, что первый запрос LINQ - это ИМХО, гораздо более прямолинейный и лаконичный, тогда как второй кажется довольно избыточным, поскольку мне приходится определять все столбцы, которые я хочу из таблицы1 дважды.

Почему эти два похожих запроса выполняют по-разному на сервере, и почему запрос 2 оказывается намного более эффективным, даже если его код гораздо менее выразителен?

Есть ли способ, чтобы я мог переписать первый запрос так же эффективно, как второй?

+0

Можете ли вы разместить SQL обеих версий? – usr

+0

@usr Конечно, позвольте мне сначала немного почистить его, как я сделал для запросов LINQ. – Kittoes0124

+0

@Kittoes Вы можете использовать [** LinqPad **] (http://www.linqpad.net/) для записи Linq и получить код Lambda и SQL – balexandre

ответ

6

LINQ 2 SQL имеет проблемы со следующей схемой:

from t in table 
group t by key into g 
from t in g //"ungroup" the grouping - this is causing a problem 
select ... 

Я думаю, что ваши соединения является инициирующей, что из-за его «Разгруппировывает» группировка. Обратите внимание, что соединение LINQ представляет собой GroupJoin, который не представлен в SQL. Подумайте об этом: как бы вы перевели мой примерный запрос? Вы должны присоединиться к table к сгруппированной версии table, вызывая безумную избыточность.

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

Существует немного менее неудобно версии:

var daily = from p in db.table1 
      group p by new 
      { 
       key1, 
       key2 
      } into g 
      select new 
      { 
       col1 = g.Key.key1, 
       col2 = g.Sum(a => a.column2) 
      } into p 
      join d in db.table2 on new { p.key1, p.key2 } equals new { d.key1, d.key2 } 
      select new 
      { 
       col1 = p.col1, 
       col2 = p.col2, 
       col3 = d.column3 
      }; 

Гнездовая удаляют менее известных select x into y синтаксиса.

+0

Черт, я действительно надеялся, что это не ответ. Я ДЕЙСТВИТЕЛЬНО не хочу, чтобы каждый из моих столбцов в таблице1 дважды, чтобы получить один столбец из таблицы2. Но я полагаю, что это не похоже на то, что у меня есть выбор в этом вопросе. – Kittoes0124

+0

@ Китто это тоже мое чувство. С другой стороны LINQ экономит столько работы, что стоит терпеть эти неприятные случаи. Желаю, чтобы команда EF предоставила компетентную поддержку LINQ или L2S не была оставлена ​​... – usr

+1

О, конечно. Количество других работ, которые сохраняет LINQ, абсолютно смехотворно, поэтому вполне можно терпеть такие вещи, как это происходит.Просто сводит меня с ума, определяя 10 столбцов + два раза по-настоящему. Большое спасибо за объяснение, ПОЧЕМУ это происходило. – Kittoes0124

Смежные вопросы