A more direct translation of your original SQL query would look like this:
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() };
The HAVING
clause is translated to an ordinary where
that is applied after grouping values using group ... by
. The result of grouping is a collection of groups (another collections), so you can use where
to filter groups. In the select
clause, you can then return information from the key (used for grouping) and aggregate of values (using g.Count()
)
EDIT: As mmcteam points out (see comments), the where g.Count() > 0
clause is not necessary, because this is already guranteed by the join
. I'll leave it there, because it shows how to translate HAVING
clause in general, so it may be helpful in other cases.