4D v18エンティティセレクション |
||||||||||||||
|
4D v18
エンティティセレクション
|
機能 | 順列なしのエンティティセレクション | 順列ありエンティティセレクション |
処理スピード | とても速い | 遅い |
メモリ内のサイズ | とても小さい | 大きい |
エンティティに対して複数の参照を格納する | 不可 | 可能 |
最適化の観点から、4D ORDA ではデフォルトでは通常順列なしのエンティティセレクションを作成しますが、orderBy( ) メソッドを使用した場合あるいは適切なオプション(以下参照)を使用した場合は除きます。このドキュメントでは、指定されている場合を除き、"エンティティセレクション"は"順列なしのエンティティセレクション"を指すこととします。
上記で書かれているように、デフォルトでは、ORDA はクエリやand( ) などの比較のオペレーションの結果として、順列なしのエンティティセレクションを作成・管理します。 順列ありのエンティティセレクションは、必要な場合において、あるいはオプションを使用して特別に要求した場合に限り作成されます。
順列ありのエンティティセレクションは以下のような場合に作成されます:
順列なしのエンティティセレクションは以下のような場合に作成されます:
順列ありのエンティティセレクションが順列なしのエンティティセレクションになった場合、重複したエンティティ参照は全て削除されます。
順列ありのエンティティセレクションを順列なしのものに変換したい場合、そのエンティティセレクションに対してand( ) オペレーションを適用するだけです。例:
//mySel は順列ありのエンティティセレクション
mySel:=mySel.and(mySel)
//これでmySel は順列なしのエンティティセレクションとなった
4D では、クライアント/サーバー環境においてエンティティセレクションを使用する、あるいはエンティティを読み込むORDAのリクエストを自動的に最適化する機構を提供しています。この最適化機構は、ネットワーク間でやり取りされるデータの量を大幅に縮小させることで4D の実行速度を向上させます。
この機能には、以下の最適化機構が実装されています:
以下のメソッドは、返されるエンティティセレクションには、ソースのエンティティセレクションの最適化コンテキストを自動的に付随させます:
例題
以下のようなコードがあるとき:
$sel:=$ds.Employee.query("firstname = ab@")
For each($e;$sel)
$s:=$e.firstname+" "+$e.lastname+" works for "+$e.employer.name // $e.employer はCompany テーブルを参照する
End for each
最適化機構のおかげで、このリクエストは学習フェーズ以降は、$sel の中で実際に使用されている属性(firstname, lastname, employer, employer.name)からのみデータを取得するようになります。
contextプロパティの使用
context プロパティを使用することで、最適化の利点をさらに増幅させることができます。このプロパティはあるエンティティセレクションで"学習した"最適化コンテキストを参照します。これを新しいエンティティセレクションを返すORDA メソッドに引数として渡すことで、その返されたエンティティセレクションでは学習フェーズを最初から省略してサーバーに使用された属性をリクエストすることができるようになります。
同じ最適化context プロパティは、同じデータクラスのエンティティセレクションに対してであればどのエンティティセレクションにも渡すことができます。エンティティセレクションを扱う全てのORDA メソッドは、context プロパティをサポートします(例えばdataClass.query( ) あるいは dataClass.all( ) メソッドなど)。ただし、 コンテキストはコードの他の部分で新しい属性が使用された際には自動的に更新されるという点に注意してください。同じコンテキストを異なるコードで再利用しすぎると、コンテキストを読み込み過ぎて、結果として効率が落ちる可能性があります。
注: 同様の機構は読み込まれたエンティティにも実装されており、それによって使用した属性のみがリクエストされるようになります(dataClass.get( ) メソッド参照)。
dataClass.query( ) メソッドを使用した例:
C_OBJECT($sel1;$sel2;$sel3;$sel4;$querysettings;$querysettings2)
C_COLLECTION($data)
$querysettings:=New object("context";"shortList")
$querysettings2:=New object("context";"longList")
$sel1:=ds.Employee.query("lastname = S@";$querysettings)
$data:=extractData($sel1) // extractData メソッドにおいて、最適化はトリガーされており、"shortList" のコンテキストが割り当てられています。
$sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
$data:=extractData($sel2) // extractData メソッドにおいて、"shortList" のコンテキストに割り当てられている最適化が適用されます。
$sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
$data:=extractDetailedData($sel3) // extractDetailedData メソッドにおいて、最適化はトリガーされており、"longList" のコンテキストが割り当てられています。
$sel4:=ds.Employee.query("lastname = Brown";$querysettings2)
$data:=extractDetailedData($sel4) // extractDetailedData メソッドにおいて、"longList" のコンテキストに割り当てられている最適化が適用されます。
エンティティセレクション型リストボックス
クライアント/サーバー環境におけるエンティティセレクション型リストボックスにおいては、そのコンテンツを表示またはスクロールする際に、最適化が自動的に適用されます。つまり、リストボックスに表示されている属性のみがサーバーにリクエストされます。
また、リストボックスのカレント項目プロパティ式 (コレクション/エンティティセレクション型リストボックス参照) を介してカレントエンティティをロードする場合には、新たな"ページモード" コンテキストが提供されます。これによって、"ページ" による追加の属性リクエストが発生しても、リストボックスの初期コンテキストのオーバーロードが避けられます。なお、ページコンテキストの生成/使用はカレント項目式を使用した場合に限ります (例えば、entitySelection[index] を介してアクセスした場合は、エンティティセレクションコンテキストが変化します)。
その後、エンティティを走査するメソッドがサーバーに送信するリクエストにも、同じ最適化が適用されます。次のメソッドは、ソースエンティティの最適化コンテキストを、戻り値のエンティティに自動的に適用します:
たとえば、次のコードは選択したエンティティをロードし、所属のエンティティセレクションを走査します。エンティティは独自のコンテキストにロードされ、リストボックスの初期コンテキストは影響されません:
$myEntity:=Form.currentElement // カレント項目式
//... なんらかの処理
$myEntity:=$myEntity.next() // 次のエンティティは同じコンテキストを使用してロードされます
エンティティセレクションオブジェクト自身は、オブジェクトとしてコピーすることはできません:
$myentitysel:=OB Copy(ds.Employee.all()) //nullを返す
しかしながら、エンティティセレクションのプロパティは取得可能です:
ARRAY TEXT($prop;0)
OB GET PROPERTY NAMES(ds.Employee.all();$prop)
//$prop にはエンティティセレクションプロパティの名前が格納される
//("length", 00", "01"...)
プロダクト: 4D
テーマ: ORDA
初出: 4D v17
デザインリファレンス ( 4D v18)