iModel.js基本查询


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;                           //EntityId,类同于数据库中数据库表的记录的Key

……

}

iModelDb (bank-end)

IModelDbiModel.js中表示iModel数据库文件的抽象类,其具有三个子类:

 

BriefcaseDb

该类表示来自iModelHubiModel的本地副本。BriefcaseDb引发一组事件,以允许应用程序和子系统跟踪其对象的生命周期,包括onOpenonOpened等。

SnapshotDb

该类表示iModel(快照)数据库文件,通常用于存档和数据传输目的。

 

StandaloneDb

该类表示的iModel数据库文件既不由iModelHub管理也不由ImodelHub进行同步读写文件。一般应用于团队协作中可能不重要单独场景。但是,StandaloneDb的设计与BriefcaseDbAPI相似且一致,从而使得用户可以很容易将其升级到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();
  }
}