Я пытаюсь выяснить, как пойти о записи запроса 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
Более прямой перевод вашего оригинального 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
предложение в общем случае, так что он может быть полезен в других случаях.
Игнорирование 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()
};
ПРИМЕЧАНИЕ. Это не проверено (и не скомпилировано), поэтому могут быть некоторые проблемы, но я бы начал с этого.
Вот как бы я это сделал. Обратите внимание, что я привык к 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()
};