[返回博客](/cn/blog) # BimRv中的可扩展存储助手

Evgeniy Tikhonov 六月 27, 2019 [\#rvt](/cn/blog/tag/rvt) [\#rfa](/cn/blog/tag/rfa)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

可扩展存储机制允许将用户数据直接存储在模型元素中。此机制不用于也不影响项目或族的参数。信息可以存储在模型的几乎任何元素中。为此，用户数据应由以下对象描述：

- 字段 — 包含数据名称、类型和单位信息，并用作访问实体中相应数据的键。
- 架构 — 数据字段对象的集合。
- 实体 — 包含与架构对应的数据的对象，可以插入到元素中。

BimRv 提供了创建和使用基于架构的数据结构的功能。此功能包含架构和字段构建器以及辅助类：

- OdBmSchemaBuilder — 允许创建架构定义。
- OdBmFieldBuilder — 在创建新字段时与 OdBmSchemaBuilder 一起使用的辅助类。
- OdBmESEntityHelper — 用于访问现有可扩展实体字段值的辅助类。
- OdBmESSchemaHelper — 允许读取现有架构属性和字段。
- OdBmESFieldHelper — 在读取字段属性和定义时与 OdBmESSchemaHelper 一起使用的辅助类。

支持以下数据类型：

- bool
- OdInt16
- OdInt32
- double
- float
- OdString
- OdGuid
- OdBmObjectId
- OdGePoint2d
- OdGePoint3d
- OdArray
- OdMap (除 double、float、OdGePoint2d 和 OdGePoint3d 外，所有类型都支持作为键)
- OdBmObject (另一个架构的实例)

使用属性，可以配置架构以限制所有用户、特定应用程序供应商或来自供应商的特定应用程序的读取和/或写入访问。

以下步骤描述了 ExtensibleStorage 的简单用法。

#### 1. 创建存储描述

要创建新模式，请使用 OdBmSchemaBuilder。

```
OdBmESSchemaBuilder schemaBuilder(pDb);
  schemaBuilder.setSchemaName(L"WireSpliceLocation")
      .setSchemaGUID(OdGUID("720080CB-DA99-40DC-9415-E53F280AA1F0"))
      .setVendorId(L"BimRv")
      .setDocumentation(L"WireSpliceLocation schema")
      .setReadAccessLevel(OdBm::ESSchemaAccessLevel::Public)
      .setWriteAccessLevel(OdBm::ESSchemaAccessLevel::Public);

```

要为存储创建字段，请使用 OdBmESFieldBuilder 类。

它包含用于设置字段属性的方法，例如：

- OdBmESFieldBuilder&amp; setDocumentation(const OdString&amp;); — 字段的描述。
- OdBmESFieldBuilder&amp; setSubSchemaGUID(const OdGUID&amp;); — 描述存储在字段中的子实体的模式的 GUID。
- OdBmESFieldBuilder&amp; setUnitType(const OdBm::UnitType::Enum); — 字段中存储的值所表示的单位类型。

创建一个数组字段和一个映射字段：

```
schemaBuilder.addSimpleField<bool>(L"BooleanField")
      .setDocumentation(L"Boolean value");
  schemaBuilder.addSimpleField<OdGePoint3d>(L"XYZField")
      .setUnitType(OdBm::UnitType::UT_Length)
      .setDocumentation(L"XYZ value");
  schemaBuilder.addArrayField<OdGUID>(L"GUIDArrayField")
      .setDocumentation(L"GUID array value");

  schemaBuilder.addMapField<OdString, OdString>(L"StringMapField")
      .setDocumentation(L"Map value");

```

字段名称用于访问字段数据以写入和读取值。在模式中定义所有字段后，调用“finish”方法以完成模式构建器。

```
OdTfClass* pSchema = schemaBuilder.finish();
OdBmObjectPtr pESEntity = OdBmDynamicObject::createObject(pSchema);
```

字段属性以及模式属性（例如单位类型、名称和文档）在创建后无法更改。

#### 2. 设置值

使用 OdBmESEntityHelper 类为实体字段设置值，例如：

```
OdBmESEntityHelper helper(pESEntity);

  helper.set<bool>(L"BooleanField", true);
  helper.set<OdGePoint3d>(L"XYZField", OdGePoint3d(20., 21., 22.),                                     OdBm::DisplayUnitType::DUT_METERS);

  OdArray<OdGUID> guids;
  guids.push_back(OdGUID("60E23C30-169B-4C46-BD2B-DC9FC476FD09"));
  guids.push_back(OdGUID("1BAD71AA-137E-4519-8D9B-B0ED1672D1BF"));
  helper.set<OdArray<OdGUID> >(L"GUIDArrayField", guids);

  OdBmMap<OdString, OdString> stringMap;
  stringMap[L"key1"] = L"value1";
  stringMap[L"key2"] = L"value2";
  helper.set<OdBmMap<OdString, OdString> >(L"StringMapField", stringMap);

```

显示单位类型参数仅用于数据类型 float、double、OdGePoint3d 和 OdGePoint2d，并为字段设置单位类型。此方法内部不执行任何转换。

对于 OdBmObjectPtr，请在 OdBmESEntityHelper.set 中使用 clone()，例如：

```
helper.set<OdBmObjectPtr> (L"EntityField", pESEntity->clone());
```

set&lt;&gt; 的模板参数必须与字段类型（在创建模式时指定）完全匹配。

#### 3. 存储数据

应用程序可以将模式实例附加到模型中的任何元素。为避免锁定共享项目中的元素，最好使用特殊元素 OdBmDataStorage。

```
OdBmDataStoragePtr pDataStorageElem = OdBmDataStorage::createObject();
    pDataStorageElem->setName(L"DataStorageElem");
    pDb->addElement(pDataStorageElem);

    pDataStorageElem->upgradeOpenMode();
    pDataStorageElem->setESEntity(pESEntity);
    pDataStorageElem->downgradeOpenMode();

```

#### 4. 读取存储

```
OdBmObjectPtr pESEntity =
        pDataStorageElem->getESEntity(OdGUID(L"720080CB-DA99-40DC-9415-E53F280AA1F0")); 
   OdBmESEntityHelper helper(pESEntity);

   bool b = helper.get<bool>(L"BooleanField");	
   OdGePoint3d xyz = helper.get<OdGePoint3d>(L"XYZField",
     OdBm::DisplayUnitType::DUT_DECIMETERS);

```

get&lt;&gt; 方法中的显示单位类型参数用于将数据转换为所需的单位，例如，先前为字段设置的值的 xyz 等于 OdGePoint3d(200., 210., 220.);

```

OdArray<OdGUID> guids = helper.get<OdArray<OdGUID> >(L"GUIDArrayField");
   OdBmMap<OdString, OdString> strings =
     helper.get<OdBmMap<OdString, OdString> >(L"StringMapField");

```

#### 5. 读取信息

要读取记录的信息，您需要获取模型元素并确定存储 GUID 和字段名称。

要获取数据库中的模式，请使用 OdBmESSchemaHelper 的静态 listSchemas 方法：

```
std::set<OdGUID> schemas = OdBmESSchemaHelper::listSchemas(pDb);
```

要获取数据库中与架构相关的元素，请使用静态 getElements 方法：

```
OdBmObjectIdArray objects = OdBmESSchemaHelper::getElements(guid, pDb);
```

您还可以使用 OdBmESFieldHelper 检索有关字段的信息，例如：

```
OdBmESFieldHelper fieldHelper(helper.getField(L"BooleanField"));
```

它包含评估字段属性的方法，例如：

- getDocumentation() — 字段的描述。
- getFieldName() — 字段的名称。
- getContainerType() — 返回字段的类型：包含一个值的简单字段或包含多个值的容器。
- getEntryIndex() — 返回字段的索引。
- getSubSchemaGUID() — 描述存储在此字段中的子实体的架构的 GUID。
- getUnitType() — 存储在此字段中的值所表示的单位类型。

OdBmESSchemaHelper 有助于获取有关架构的信息：

```
OdBmESEntityHelper helper(pESEntity);
OdBmESSchemaHelper schHelper(helper.getSchema());
```

该帮助器具有以下方法：

- getDocumentation() — 架构的描述。
- getVendorId() — 可以在供应商访问级别下访问此架构实体的第三方供应商的字符串 ID。
- getSchemaName() — 架构的名称。
- getSchemaGUID() — 架构的标识符。
- getReadAccessLevel() — 架构的读取访问级别。
- getWriteAccessLevel() — 架构的写入访问级别。

## 今天就开始行动

**免费试用 ODA 软件 60 天。  
无风险，无需信用卡。**

[免费试用](https://www.opendesign.com/cn/free-trial)
