The second solution is exactly what I’m looking for. I modified it this way (it might be useful for someone else):
var exp = db.From<Entities.Object>();
exp.And(x => !x.ParentId.HasValue);
var q = db.From<Entities.Object>(db.TableAlias("x"));
q.Where($$"x.{q.Column<Entities.Object>(qp => qp.ParentId)}={exp.Column<Entities.Object>(ep => ep.Id, true)}");
var subSql = q.Select(Sql.Count("*")).ToSelectStatement();
exp = exp.Select(x =>
new
{
x,
ChildCount = Sql.Custom($$"({subSql})"),
TotalRows = Sql.Custom("COUNT(*) OVER()")
});
var ds = db.Select<ObjectListItem>(exp);
…query above generate this sql:
SELECT "object"."id", "object"."parent_id", "object"."name",
(SELECT COUNT(*) FROM "object" "x" WHERE x."parent_id" = "object"."id") AS ChildCount,
COUNT(*) OVER () AS TotalRows
FROM "object"
WHERE NOT(("parent_id" IS NOT NULL))
Ok, I also mention it a little intentionally :-))
It’s possible to notice, that “parent_id” is not prefixed with “object” like columns in Select clause - with more same tables, this might be a problem, but maybe it’s treated, I admit that I don’t know.
But, when I add “TableAlias” for “main” table in this way:
var exp = db.From<Entities.Object>(db.TableAlias("obj"));
//...rest of code is same as above
I get this result with error:
SELECT "object"."id", "object"."parent_id", "object"."name",
(SELECT COUNT(*) FROM "object" "x" WHERE x."parent_id" = "object"."id") AS ChildCount,
COUNT(*) OVER () AS TotalRows
FROM "object" "obj"
WHERE NOT(("obj"."parent_id" IS NOT NULL))
Is there some magic how to make them in the Select clause “obj” instead of “object” (and same for subquery). And also tell in the exp.Column<>(…) which table alias to use, especially with more joined (and aliased) tables?
Thank you!
Tom