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();
}
}