Запрос Linq с агрегатной функцией

Я пытаюсь выяснить, как пойти о записи запроса linq для выполнения агрегата как запрос SQL ниже:

select d.ID, d.FIRST_NAME, d.LAST_NAME, count(s.id) as design_count
from tbldesigner d inner join
TBLDESIGN s on d.ID = s.DESIGNER_ID
where s.COMPLETED = 1 and d.ACTIVE = 1
group by d.ID, d.FIRST_NAME, d.LAST_NAME
Having COUNT(s.id) > 0

Если это даже возможно с запросом linq, мог кто-то предоставлять мне пример. Заранее спасибо, Billy

1
задан Billy Logan 29 May 2010 в 12:49
поделиться

3 ответа

Более прямой перевод вашего оригинального SQL-запроса будет выглядеть так:

var q = 
    // Join tables TblDesign with TblDesigner and filter them
    from d in db.TblDesigner 
    join s in db.TblDesign on d.ID equals s.DesignerID
    where s.Completed && d.Active
    // Key and values used for grouping (note, you don't really need the
    // value here, because you only need Count of the values in a group, but
    // in case you needed anything from 's' or 'd' in 'select', you'd write this
    let value = new { s, d } 
    let key = new { d.ID, d.FirstName, d.LastName }
    group value by key into g 
    // Now, filter the created groups (return only non-empty) and select 
    // information for every group
    where g.Count() > 0
    select { ID = g.Key.ID, FirstName = g.Key.FirstName, 
             LastName = g.Key.LastName, Count = g.Count() };

Пункт HAVING переводится в обычный where, который применяется после группировки значений с помощью group ... by. Результатом группировки является коллекция групп (еще одна коллекция), поэтому вы можете использовать where для фильтрации групп. В предложении select можно вернуть информацию из ключа (используемого для группировки) и совокупности значений (используя g.Count())

EDIT: Как указывает mmcteam (см. комментарии), пункт where g.Count() > 0 не является необходимым, поскольку это уже гарантируется join. Я оставлю его здесь, потому что он показывает, как переводить HAVING предложение в общем случае, так что он может быть полезен в других случаях.

2
ответ дан 3 September 2019 в 00:14
поделиться

Игнорирование s.id, который меня сбивает (см. Мой комментарий к вопросу), это простой запрос, который сгенерирует предложение наличия. Конечно, в данном случае это бесполезный пример, поскольку в этом случае счет всегда будет больше 0.

В любом случае, если вы используете SQL to Entities, вы должны использовать сопоставление сущностей для доступа к отношениям внешнего ключа вместо ручного выполнения соединения или подзапроса.

var results = from d in db.tbldesigner 
              where d.TBLDESIGN.COMPLETED && d.ACTIVE 
              group d by new {d.ID, d.FIRST_NAME, d.LAST_NAME} into g
              where g.Count() >= 0
              select new {
                 d.ID, d.FIRST_NAME, d.LAST_NAME,
                 Count = g.Count()
              };

ПРИМЕЧАНИЕ. Это не проверено (и не скомпилировано), поэтому могут быть некоторые проблемы, но я бы начал с этого.

0
ответ дан 3 September 2019 в 00:14
поделиться

Вот как бы я это сделал. Обратите внимание, что я привык к linqtosql и не знаю, есть ли отличия для запроса в linqtoentities.

var query =
  from d in myObjectContext.tbldesigner
  where d.ACTIVE == 1
  let manys =
    from s in d.tbldesign
    where s.COMPLETED == 1
    select s
  where manys.Count() > 0
  select new
  {
    d.ID, d.FIRST_NAME, d.LAST_NAME,
    DesignCount = manys.Count()
  };
0
ответ дан 3 September 2019 в 00:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: