OutSystemsの複合データ型であるStructure/Entity/RecordをExtension (C#) に渡したら、データの型がどうなるかを確認してみた。
環境
Personal Environment(Version 11.17.0 (Build 36291))
Service Studio(Version 11.53.13)
Integration Studio(Version 11.11.5)
サンプルモジュール
Forgeコンポーネント: HousesoftSampleExtensionのV1.0.3。
- Demoモジュール > MainFlow > AttributeInDotNet Screen
- サンプルAction (Extension): RetrieveAttributeInformation
確認結果のまとめ
- 渡した値がStructure/Recordの場合、属性はFieldとして定義されており、TypeオブジェクトのGetFieldsで取得できる。名前は「ss<属性名>」
- 渡した値がEntityの場合、属性はPropertyとして定義されており、TypeオブジェクトのGetPropertiesで取得できる。名前は「ss<属性名>」
- 渡した値がジョインしたEntityの場合、渡した値の直下にはFieldとしてジョインされた各Entityが含まれる。名前は「ssEN」
確認方法
- 入力変数(object型、呼び出すときにBuilt-In FunctionのToObjectで変換して渡す)のTypeオブジェクトを取得
- Typeオブジェクトを経由して入力変数のFieldを列挙して名前・型を取得して出力変数のリストに追加
- Typeオブジェクトを経由して入力変数のPropertyを列挙して名前・型を取得して出力変数のリストに追加
public void MssRetrieveAttributeInformation(object ssInput, out RLAttributeInfomationRecordList ssAttributeInformationList) {
ssAttributeInformationList = new RLAttributeInfomationRecordList();
var type = ssInput.GetType();
var fields = type.GetFields();
foreach (var field in fields)
{
var temp = new RCAttributeInfomationRecord();
temp.ssSTAttributeInfomation = new STAttributeInfomationStructure()
{
ssName = field.Name,
ssDataType = field.FieldType.FullName,
ssMemberType = "Field"
};
ssAttributeInformationList.Add(temp);
}
var props = type.GetProperties();
foreach (var prop in props)
{
var temp = new RCAttributeInfomationRecord();
temp.ssSTAttributeInfomation = new STAttributeInfomationStructure()
{
ssName = prop.Name,
ssDataType = prop.PropertyType.FullName,
ssMemberType = "Property"
};
ssAttributeInformationList.Add(temp);
}
}
データの種類ごとの確認結果
以前書いたExtensionのC#コードに渡ってくるデータの型について と同じ種類のデータを使って確認した。各種類のデータに対して属性情報を抜き出してみた結果は以下の通り(リスト系のデータに対するテストは除外した)。
Structure:シンプル
入力データの定義
Text型・Integer型のAttributeを持つStructure SampleStructureを使ってテスト。
結果
各属性は、C#では、Structureに対応するClassのFieldとして定義される(TypeオブジェクトのGetFieldsで取得できる)。
Field名:ss<属性名>
型:対応するビルトインデータ型(TextならSystem.Stringなど)
Structure:子Structure有
入力データの定義
こちらは、同じStructureであっても、Attributeに別のStructure型のものを持つ入れ子形式。
結果
各属性はFieldとして定義される。
Field名:ss<属性名>
型:OutSystemsのBasic Data Typeであれば、対応するビルトインデータ型(Date TimeならSystem.DateTime)。Structureについては、「ss<Structureを定義したモジュール名>.ST<Structure名>Structure」。
Structure:Extensionに定義
入力データの定義
シンプルなStructureをExtension内に定義した場合のテスト。
結果
各属性はFieldとして定義される。
Field名:ss<属性名>
型:対応するビルトインデータ型(TextならSystem.Stringなど)
Entity:単独・1レコード
入力データの定義
Extensionに渡る値が、StructureとEntityでは扱いが異なる。
以下のようにService Studioで定義したEntity型の1レコードを直接Extensionに渡した場合。
結果
Entityの場合、属性はFieldとPropertyの両方に定義される。つまり値の本体はprivateのFieldとして名前に「_」(アンダースコア)をつけて定義され、Class外には直接Fieldを公開せず、Propertyを経由して操作させる、というやり方。ここではPropertyの方を見ておく。
こういった定義をC#のコードで見るには、外部DB用のExtensionを作成し、そのソースコードをIntegration Studioで生成するとよい。
Property名:ss<属性名>
型:対応するビルトインデータ型(TextならSystem.Stringなど)
Entity:ジョイン・1レコード
入力データの定義
こちらは、複数のEntityをAggregateでジョインし、結果のList.Currentを渡した場合。
以下のように2 EntityをジョインするAggregateを定義し、
ExtensionのActionにはその結果の1レコード、List.Currentを渡している。
ToObject(GetSampleEmployees.List.Current)
結果
ここではジョインした結果を渡しているため、入力変数の直下には、ジョインした各Entity型がぶら下がる。
この場合、Entity型に対応する属性はFieldとして定義されている。
Field名:ss
型:「ss<モジュール名>.EN<Entity名>EntityRecord」
Record:Data Type Editor
入力データの定義
Service Studio上でData TypeとしてRecordを選択すると、その場でRecordの型を定義できる。その形式の入力を使ったテスト。
以下のようにText型の属性のみを持つRecordを定義した。
結果
各属性はFieldとして定義される。
Field名:ss<属性名>
型:対応するビルトインデータ型(TextならSystem.Stringなど)