iModel.js (bank-end)基本查询
通过了解为什么使用Entity,有助于更好的使用iModel.js相关API。
通过使用Entity Framework,开发者不需要为数据访问编写所有需要的ADO管道代码(即创建数据库连接,打开数据库,执行查询,返回数据,关闭数据库),因此可以节省很多开发时间。我们可以使用更高级的语言(例如C++,C#,typescript等)来编写所有的数据访问逻辑而不是编写SQL查询和存储过程。因为数据库表没有更高级的关系(如继承),然而Entity是可以有的。所以,业务模型(也就是概念模型)可以使用实体间的关系来适配应用领域。底层的数据存储可以相对轻松地被取代,因为所有的数据访问逻辑都呈现在应用层而不是数据层。(若要了解更多,请参考微软的Entity Framework)。
iModel.js中所有的需要持久化的类都实现了接口EntityProps,其中EntityProps接口定义如下所示:
interface EntityProps
{
classFullName:string; //此Entity的全名,类同于数据库中数据库表名。
id?:string; //此Entity的Id,类同于数据库中数据库表的记录的Key。
……
}
IModelDb是iModel.js中表示iModel数据库文件的抽象类,其具有三个子类:
BriefcaseDb |
该类表示来自iModelHub的iModel的本地副本。BriefcaseDb引发一组事件,以允许应用程序和子系统跟踪其对象的生命周期,包括onOpen,onOpened等。 |
SnapshotDb |
该类表示iModel(快照)数据库文件,通常用于存档和数据传输目的。
|
StandaloneDb |
该类表示的iModel数据库文件既不由iModelHub管理也不由ImodelHub进行同步读写文件。一般应用于团队协作中可能不重要单独场景。但是,StandaloneDb的设计与BriefcaseDb的API相似且一致,从而使得用户可以很容易将其升级到iModelHub。 |
因此,根据不同的需要,可以选择使用不同的子类。在本章示例中,我们以SnapshotDb为例。
我们首先创建一个SnapshotDb对象,然后执行一些查询。
import { SnapshotDb, Model, GeometricModel, DrawingModel, } from "@bentley/imodeljs-backend"; import { ECSqlStatement } from "@bentley/imodeljs-backend"; import { DbResult } from "@bentley/bentleyjs-core"; class SnapshotDbExample { public constructor(filePath: string) { this._filePath = filePath; this._imodel = undefined; } public openIModel() { this._imodel = SnapshotDb.openFile(this._filePath); if (this._imodel) { console.log(this._filePath + " 打开成功"); return true; } else { console.log(this._filePath + " 打开失败"); return false; } } public dispose() { if (this._imodel != undefined) { this._imodel.close(); } } public async QueryIModel() { if (this._imodel == undefined) { return; } /* 1.查询该imodel数据文件路径*/ const imodel = this._imodel; console.log(imodel.filePath); /* 2.查询该imodel可读性*/ if (imodel.isReadonly) { console.log("只读"); } else { console.log("可读可写"); } /* 3.查询该imodel中所有的model*/ { const modelIdSet = imodel.queryEntityIds({ from: Model.classFullName }); for (const modelId of modelIdSet.values()) { const modelProp = imodel.models.tryGetModelProps(modelId); if (modelProp != undefined) { // console.log(modelProp); } } } /* 4.查询该imodel中所有的GeometricModel*/ { const modelIdSet = imodel.queryEntityIds({ from: GeometricModel.classFullName, }); for (const modelId of modelIdSet.values()) { const modelProp = imodel.models.tryGetModel(modelId); if (modelProp != undefined) { // console.log(modelProp); } } } /* 5. 查询该imodel中所有的DrawingModel*/ { const sql = `select * from ${DrawingModel.classFullName}`; imodel.withPreparedStatement(sql, (statement: ECSqlStatement) => { while (DbResult.BE_SQLITE_ROW === statement.step()) { console.log(statement.getRow().id); } }); } /* 6.根据已知Element Id查询其属性值。*/ { /* 注:id为0x300000002f5的Element的属性如下所示: { classFullName: 'ProcessFunctional:SIGNALLINE', code: { scope: '0x1', spec: '0x1', value: '' }, federationGuid: '4cc96158-0484-47dd-bffe-447c1b4e422e', id: '0x300000002f5', model: '0x20000000001', openPlantTypeName: 'INSTLINE_ELECTRIC', pLANT_AREA: '50', sERVICE: 'HPS', sYSTEM: 'SW', uNIT: '1', userLabel: 'IL' } */ const elementProp = imodel.elements.tryGetElementProps("0x300000002f5"); if (elementProp) { console.log((elementProp as any).pLANT_AREA); //将输出50 } } } private _filePath: string; private _imodel: SnapshotDb | undefined; } export async function SnapshotDbExample_Handle() { const filePath = "../data/Baytown.bim"; const example = new SnapshotDbExample(filePath); if (example.openIModel()) { await example.QueryIModel(); example.dispose(); } }