Useful ECSQL Queries
The following ECSQL select statements are examples of useful queries that an app backend or a service might want to perform. They are written in a form that can be executed in backend code.
Select Elements in a particular Model
const modelId: Id64String = IModelDb.repositoryModelId;
// eslint-disable-next-line @typescript-eslint/no-deprecated
iModel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${Element.classFullName} WHERE Model.Id=:modelId`, (statement: ECSqlStatement) => {
statement.bindId("modelId", modelId);
while (DbResult.BE_SQLITE_ROW === statement.step()) {
// do something with each row
}
});
Select Top-Level Elements in a particular Model
const modelId: Id64String = IModelDb.repositoryModelId;
// eslint-disable-next-line @typescript-eslint/no-deprecated
iModel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${Element.classFullName} WHERE Model.Id=:modelId AND Parent.Id IS NULL`, (statement: ECSqlStatement) => {
statement.bindId("modelId", modelId);
while (DbResult.BE_SQLITE_ROW === statement.step()) {
// do something with each row
}
});
Select Child Elements
const parentId: Id64String = IModelDb.rootSubjectId;
// eslint-disable-next-line @typescript-eslint/no-deprecated
iModel.withPreparedStatement(`SELECT ECInstanceId AS id FROM ${Element.classFullName} WHERE Parent.Id=:parentId`, (statement: ECSqlStatement) => {
statement.bindId("parentId", parentId);
while (DbResult.BE_SQLITE_ROW === statement.step()) {
// do something with each row
}
});
Look up element by code value
// Suppose an iModel has the following breakdown structure:
// * The root subject
// * * Subject with CodeValue="Subject1"
// * * * PhysicalPartition with CodeValue="Physical"
// Suppose you want to look up the PhysicalPartition whose code value is "Physical".
// You could write the following query to find it. This query specifies that the
// element you want is a PhysicalPartition, it has a code value of "Physical",
// and it is a child of a Subject named "Subject1".
// eslint-disable-next-line @typescript-eslint/no-deprecated
const partitionIds: Id64Set = iModel.withPreparedStatement(`
select
[partition].ecinstanceid
from
${PhysicalPartition.classFullName} as [partition],
(select ecinstanceid from ${Subject.classFullName} where CodeValue=:parentName) as parent
where
[partition].codevalue=:partitionName and [partition].parent.id = parent.ecinstanceid;`,
// eslint-disable-next-line @typescript-eslint/no-deprecated
(stmt: ECSqlStatement) => {
stmt.bindValue("parentName", "Subject1");
stmt.bindValue("partitionName", "Physical");
const ids: Id64Set = new Set<Id64String>();
while (stmt.step() === DbResult.BE_SQLITE_ROW)
ids.add(stmt.getValue(0).getId());
return ids;
});
assert.isNotEmpty(partitionIds);
assert.equal(partitionIds.size, 1);
for (const eidStr of partitionIds) {
assert.equal(iModel.elements.getElement(eidStr).code.value, "Physical");
}
Discover element classes in an iModel
When exploring an unfamiliar iModel, it is useful to see which element classes are present and how many instances of each exist. This query joins element data with the ECDbMeta schema to produce a summary:
SELECT s.Name || ':' || c.Name ClassName, count(*) InstanceCount
FROM bis.Element e
JOIN meta.ECClassDef c ON e.ECClassId = c.ECInstanceId
JOIN meta.ECSchemaDef s ON s.ECInstanceId = c.Schema.Id
GROUP BY s.Name, c.Name
ORDER BY InstanceCount DESC
For more meta query patterns, see the Meta Queries tutorial and the ECDbMeta ECSchema reference.
As an alternative, you can use the IModelDb.queryEntityIds convenience method for simple cases.
Last Updated: 30 March, 2026
Found something wrong, missing, or unclear on this page? Raise an issue in our repo.