Linq Query с агрегатной функцией - PullRequest
1 голос
/ 29 мая 2010

Я пытаюсь выяснить, как написать запрос 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, может кто-нибудь привести пример. Заранее спасибо, Билли

Ответы [ 3 ]

2 голосов
/ 29 мая 2010

Более прямой перевод вашего исходного 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 в целом, так что это может быть полезно в других случаях.

0 голосов
/ 29 мая 2010

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

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

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 голосов
/ 29 мая 2010

Вот как бы я это сделал. Обратите внимание, что я привык к 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()
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...