Microsoft Rules Composer を使用して、ルールの実行を最適化するためにアクションに control 関数を追加する
適用対象: Azure Logic Apps (Standard)
重要
この機能はプレビュー段階にあり、「Microsoft Azure プレビューの追加使用条件」が適用されます。
このガイドでは、Microsoft Rules Composer を使用して、ルール内のアクションに control 関数を追加して、ルールの実行を最適化する方法について説明します。 control 関数は、アプリケーションまたはルール セットがルール エンジンのワーキング メモリ内のファクトを制御するのに役立ちます。 これらの関数には、ファクトとして使用できる .NET オブジェクトと TypedXmlDocument エンティティ用の Assert、Clear、Halt、Retract、RetractByType、Reassert、Update などがあります。 ワーキング メモリにファクトが存在すると、エンジンが評価する条件と実行されるアクションが促進されます。
前提条件
Microsoft Rules Composer をダウンロードしてインストールします。
作業するルールセットを含む XML ファイル。
ファクトを追加するには、RuleSet エクスプローラー ウィンドウからポイントする XML ドキュメントでその値を指定します。 または、ファクト作成者を使用して、.NET オブジェクトをファクトとして含む配列をルール エンジンに提供することもできます。 詳細については、「ファクト クリエーターとレトリバーの構築」を参照してください。
Assert 関数
ルール エンジンのワーキング メモリにオブジェクト インスタンスを追加するには、Microsoft Rules Composer の Assert 関数を使用します。 エンジンは、一致、競合解決、アクションの各フェーズを使用し、そのインスタンスに対して記述された条件とアクションに基づいて各オブジェクト インスタンスを処理します。
次の表は、サポートされているアサートされたエンティティとインスタンス型の Assert 関数の動作をまとめたものです。これには、アサートされた各エンティティのエンジンで作成された結果のインスタンスの数や、識別のために各インスタンスに適用される型が含まれます。
エンティティ | アサートされたインスタンスの数 | インスタンスの種類 |
---|---|---|
.NET オブジェクト | 1 (オブジェクト自体) | 完全修飾 .NET クラス |
TypedXmlDocument | 1 ~ N 個の TypedXmlDocument: 作成されるセレクター バインドとドキュメントのコンテンツに基づく | DocumentType.Selector |
.NET オブジェクトのアサート
ルール エンジンは、基本的な .NET スカラー型と参照型のオブジェクトをネイティブにサポートします。 アサートされた .NET オブジェクトの処理は、処理の種類の中で最も簡単です。
Microsoft Rules Composer では、ルール内から .NET オブジェクトをアサートできます。
Microsoft Rules Composer で、作業するルール ストアを含む XML ファイルを読み込みます。
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Assert 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[.NET クラス] を選択します。
[.NET クラス] タブで、オブジェクトのコンストラクター メソッドを、Assert アクションの引数にドラッグします。
Microsoft Rules Composer は、コンストラクター メソッドをルール定義内の CreateObject 呼び出しに変換します。
Note
ルール エンジンには CreateObject 関数がありますが、この関数は Microsoft Rules Composer では別の関数として表示されません。
各オブジェクトは個別のオブジェクト インスタンスとして動作メモリにアサートされます。つまり、IF Object.Property = 1
など、オブジェクトの型を参照する各述語によってインスタンスが分析されます。 インスタンスは、ルールの条件の結果に基づいて、型を参照するルール アクションでも使用できます。
たとえば、次のようなルールがあるとします:
規則 1
IF A.Value = 1
THEN A.Status = "good"
規則 2
IF B.Value = 1
THEN A.Status = "good"
ルール 1 では、A インスタンスの値が 1 の場合にのみ、"状態" プロパティが更新されます。 ただし、ルール 2 では、条件が true と評価されると、すべての A インスタンスの状態が更新されます。 実際、複数の B インスタンスが存在する場合は、いずれかの B インスタンスの条件が true と評価されるたびに、A のインスタンスが更新されます。
TypedXmlDocument エンティティをアサートする
Microsoft Rules Composer では、ルール内から TypedXmlDocument エンティティをアサートできます。
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Assert 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブで、Assert アクションの引数にノードをドラッグします。
XML ドキュメントは基本的にテキストですが、フィールドの値は、ルールの作成時に指定された型に基づく任意の型である可能性があります。 フィールドは XPath 式であるため、ノードセットが返される可能性があります。つまり、セット内の最初の項目が値として使用されます。
TypedXmlDocument エンティティがファクトとしてアサートされると、ルール エンジンは、ルールで定義されたセレクターに基づいて、TypedXmlDocument 子インスタンスを作成します。 セレクターは、XML ドキュメントのノードを分離するための方法として、フィールドは、セレクター内の特定の項目を識別するものとしてとらえることができます。 ルール エンジンは、1 つのセレクター内のすべてのフィールドをオブジェクトとしてグループ化します。
セレクターは XPath 式でもあります。 ファクト エクスプローラーで、[XML スキーマ] タブでノードを選択すると、Microsoft Rules Composer によって、すべてのノードの "XPath Selector" プロパティと、子ノードを含まないノードの "XPath フィールド" プロパティが自動的に入力されます。 または、必要に応じて、[XPath セレクター] と [XPath フィールド] に独自の XPath 式を入力できます。 セレクターが XML ドキュメント内の複数の部分と一致する場合、この型の複数のオブジェクトがルール エンジンのワーキング メモリにアサートされるか、または取り消されます。
同じドキュメント内でも、複数のセレクターを使用することができます。 そうすることで、ドキュメントのさまざまな部分を表示できます。たとえば、1 つのセクションが注文で、別のセクションに配送先住所が含まれているとします。 ただし、作成されたオブジェクトは、作成した XPath 文字列によって定義されていることに注意してください。 別の XPath 式を使用する場合、式が同じノードに解決された場合でも、結果は TypedXmlDocument エンティティ一意になります。
たとえば、次のような XML コードがあるとします:
<root>
<order customer="Joe">
<item name="router" quantity="10" cost="550" />
<item name="switch" quantity="3" cost="300" />
</order>
<order customer="Jane">
<item name="switch" quantity="1" cost="300" />
<item name="cable" quantity="23" cost="9.99" />
</order>
</root>
セレクター /root/order、または //order を使用すると、次のオブジェクトがエンジンのワーキング メモリに追加されます:
オブジェクト 1
<order customer="Joe">
<item name="router" quantity="10" cost="550" />
<item name="switch" quantity="3" cost="300" />
</order>
オブジェクト 2
<order customer="Jane">
<item name="switch" quantity="1" cost="300" />
<item name="cable" quantity="23" cost="9.99" />
</order>
各セレクター内で、XPaths は個々のフィールドを参照します。 そのため、セレクター /root/order/item、//order/item、または //item を使用すると、Joe の 2 つの項目と Jane の 2 つの項目を含む次のオブジェクトがエンジンのワーキング メモリに追加されます:
<root>
<order customer="Joe">
</order>
<order customer="Jane">
</order>
</root>
各オブジェクトは、@name、@quantity、@cost の 3 つのフィールドにアクセスできます。 オブジェクトは元のドキュメントへの参照であるため、親フィールド (../@customer など) を参照できます。
ルール エンジンでは、バックグラウンドで、XmlConvert 関数を使用して、テキスト フィールド値をサポートされている任意の型に変換できます。 このオプションを指定するには、Microsoft Rules Composer で型を設定します。 変換できない場合、エンジンは例外をスローします。 ブール型と double 型をそれぞれの型 (文字列またはオブジェクト) としてのみ取得できます。
Clear 関数
ルール エンジン インスタンスのワーキング メモリと議題をリセットするには、Microsoft Rules Composer の Clear 関数を使用します。 ワーキング メモリと議題の詳細については、「ルール エンジンの最適化」を参照してください。
ルール エンジンのワーキング メモリと議題をリセットする
RuleSet Explorer ウィンドウで、ルール エンジンのワーキング メモリと議題をクリアするルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Clear 組み込み関数をアクションとして追加します。
Clear 関数は引数を受け取っていません。
Halt 関数
ルール エンジンによる現在の実行を停止するには、Microsoft Rules Composer の Halt 関数を使用します。
ルール セットの実行を停止する
RuleSet Explorer ウィンドウで、ルール セットの実行を停止するルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Halt 組み込み関数をアクションとして追加します。
Halt 関数は、1 つの ブール引数を受け取ります。 値を true として指定すると、ルール エンジンは保留中の候補ルールを含む議題をクリアします。
Ruleset.Execute メソッドは、RuleEngine.Execute メソッドのラッパーであり、次のコードのようなコードを使用します:
RuleEngine.Assert(facts);
RuleEngine.Execute();
RuleEngine.Retract(facts);
Ruleset.Execute メソッドを使用してルール セットを実行すると、Halt 関数の実行時に、ルール エンジンは Ruleset.Execute メソッドに制御を返します。 Ruleset.Execute メソッドはファクトを取り消して、呼び出し元に制御を戻します。 この場合、停止したルールセットの実行を再開できません。
ただし、RuleEngine.Execute メソッドを直接使用してルール セットを実行する場合は、2 つの呼び出しの間に必要なオブジェクトを取り消さなければ、RuleEngine.Execute を再度呼び出すことで、次の保留中のルールの実行で停止したルール セットの実行を再開できます。
Note
Ruleset.Execute メソッドは、パフォーマンスを向上させるためにルール エンジン インスタンスをキャッシュします。 RuleEngine.Execute メソッドを直接使用する場合、ルール エンジン インスタンスはキャッシュされません。
次のサンプル コードは、停止したルール セットの実行を再開する方法を示しています:
// Assert facts into working memory of the rules engine instance.
RuleEngine.Assert(facts);
// Execute the ruleset.
RuleEngine.Execute();
// The ruleset invokes the Halt method when executing actions.
// Control returns here when the Halt function is called.
// When engine halts, do the following tasks.
// Add your code here.
// Resume the halted rules engine execution.
RuleEngine.Execute();
// Retract or remove facts from working memory in the rules engine.
RuleEngine.Retract(facts);
Retract 関数
ルール セットおよびルール エンジンのワーキング メモリからオブジェクトを削除するには、Microsoft Rules Composer の Retract 関数を使用します。
.NET オブジェクトを取り消す
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Retract 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[.NET クラス] を選択します。
[.NET クラス] タブから、アセンブリやメソッドではなく、必要なクラスを Retract パラメーターの引数にドラッグします。
メソッドを Retract 関数にドラッグすると、エンジンは、メソッドから返されるオブジェクトを取り消そうとします。
.NET オブジェクトの取り消しには、次の影響があります:
オブジェクトを使用している議題のアクションは、議題から削除されます。
Note
議題の上位にある他のアクションは、Retrtact 関数を使用する前に既に実行されている可能性があります。
述語でオブジェクトを使用するルールでは、議題にアクションが存在する場合、アクションが議題から削除されます。
エンジンはオブジェクトを評価しなくなりました。
TypedXmlDocument エンティティを取り消す
ルール エンジンにアサートされた元の TypedXmlDocument エンティティを取り消すか、または親 XmlDocument エンティティから作成された TypedXmlDocument 子エンティティのうちの 1 つを取り消すことができます。
次のような XML の例があるとします:
<order>
<orderline customer="Joe" linenumber="001">
<product name="router" quantity="10" cost="550" />
</orderline>
<orderline customer="Jane" linenumber="002">
<product name="switch" quantity="1" cost="300" />
</orderline>
</order>
order オブジェクトに関連付けられている TypedXmlDocument エンティティを取り消すか、orderline オブジェクトに関連付けられている TypedXmlDocument エンティティの一方または両方を取り消すことができます。 すべての TypedXmlDocument エンティティは、XML ツリー階層の最上位レベルの TypedXmlDocument ノードの上に表示される TypedXmlDocument エンティティではなく、最初にアサートされた最上位 TypedXmlDocument エンティティに関連付けられます。
たとえば、製品は、orderline オブジェクトの下の TypedXmlDocument エンティティであり、orderline の TypedXmlDocument エンティティではなく、order の TypedXmlDocument エンティティに関連付けられています。 ほとんどのインスタンスで、この区別は重要ではありません。 ただし、order オブジェクトを取り消すと、orderline オブジェクトと product オブジェクトも取り消されます。 orderline オブジェクトを取り消すと、そのオブジェクトだけが取り消されます。product オブジェクトは取り消されません。
エンジンは、TypedXmlDocument エンティティが最初にアサートされたときに作成された、TypedXmlDocument インスタンス オブジェクト インスタンスでのみ動作し、追跡します。 ルール セット内のセレクターを使用して選択されたノードの兄弟ノードなど、追加のノードを作成した場合、TypedXmlDocument エンティティが作成およびアサートされない限り、これらのノードはルールで評価されません。 これらの新しい下位レベル TypedXmlDocument インスタンスをアサートすると、エンジンはルール内のインスタンスを評価しますが、最上位レベル TypedXmlDocument エンティティにはそれらの知識がありません。 最上位レベルの TypedXmlDocument が取り消される場合、新しく個別にアサートされた TypedXmlDocument エンティティは自動的に取り消されません。 その結果、新しいノードが作成されたら、XmlDocument 全体に対して Retract と Reassert を実行します。これが最も一般的で簡単な手運です。
TypedXmlDocument クラスには、アクションの一部としてカスタム .NET メンバー内で呼び出すことができる便利なメソッドが用意されています。 これらのメソッドには、TypedXmlDocument または親 TypedXmlDocument に関連付けられている XmlNode を取得する機能が含まれます。
最上位レベルの TypedXmlDocument エンティティを取り消す
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Retract 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブから、スキーマの最上位ノードを Retract 関数の引数にドラッグします。
この最上位ノードは、.xsd 拡張子で終わり、ドキュメント要素ノードではなくドキュメント ルート ノードを表します。 ノードには、初期 TypedXmlDocument を参照する / セレクターがあります。 親 TypedXmlDocument を取り消すと、TypedXmlDocument に関連付けられているすべての TypedXmlDocument 子エンティティが、Assert 関数を呼び出して作成されたすべての TypedXmlDocument エンティティを含め、ワーキング メモリから削除されます。ルールセットで使用されるセレクターに基づいています。
子 TypedXmlDocument エンティティを取り消す
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Retract 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブから、子ノードを Retract 関数の引数にドラッグします。
RetractByType 関数
ルール エンジンのワーキング メモリから指定した型のすべてのオブジェクトを削除するには、Microsoft Rules Composer の RetractByType 関数を使用します。 この関数は、Retract 関数とは異なり、特定の種類の特定の項目のみが削除されます。
特定の型を持つすべての .NET オブジェクトを取り消す
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、RetractByType 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[.NET クラス] を選択します。
.NET クラス タブから、クラスを RetractByType 関数の引数にドラッグします。
特定の型を持つすべての TypedXmlDocument エンティティを取り消す
RetractByType は、同じ DocumentType.Selector を持つすべての TypedXmlDocument エンティティを削除します。
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、RetractByType 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブから、適切なノードを RetractByType 関数にドラッグします。
Retract 関数と同様に、ドキュメント ルート ノードで RetractByType 関数を使用する場合、このアクションは、その DocumentType でアサートされたすべての TypedXmlDocument エンティティだけでなく、すべての子 TypedXmlDocument エンティティも取り消します。または、ツリー階層内の XmlNode ノードを します。これらの親 TypedXmlDocument エンティティに関連付けられています。
Reassert 関数
エンジンのワーキング メモリに既に存在するオブジェクトに対して Assert 関数を呼び出すには、Microsoft Rules Composer の Reassert 関数を使用します。 この動作は、オブジェクトの Retract コマンドを発行した後、Assert コマンドを発行することと同じです。
たとえば、.NET オブジェクトで Reassert 関数を使用する場合、ルール エンジンは次の手順を実行します:
.NET オブジェクトをワーキング メモリから取り消します。
述語またはアクションでオブジェクトを使用するルールの議題に対するすべてのアクションを削除します。
.NET オブジェクトをワーキング メモリにアサートし直し、新しくアサートされたオブジェクトとして評価します。
述語でオブジェクトを使用するすべてのルールを再評価し、必要に応じてそれらのルールのアクションを議題に追加します。
以前に true と評価されたアクションでオブジェクトのみを使用するように評価されたすべてのルールのアクションを議題に読み取りました。
.NET オブジェクトを再アサートする
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Reassert 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[.NET クラス] を選択します。
[.NET クラス] タブから、クラスを RetractByType 関数の引数にドラッグします。
TypedXmlDocument エンティティを再アサートする
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Reassert 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブから、必要なエンティティ ノードを Reassert 関数の引数にドラッグします。
最上位レベル TypedXmlDocument エンティティを再アサートする場合、最上位 TypedXmlDocument エンティティが最初にアサートされたときに作成された TypedXmlDocument 子エンティティは、各 TypedXmlDocument 子エンティティの状態に応じて動作が異なります。
たとえば、新規または既存の子エンティティが "ダーティー" の場合、アクションを使用してルールセット内で少なくとも 1 つのフィールドが変更された場合、Assert 関数または Reassert 関数がその子に対して実行されます。 ダーティーでない既存の子は、ワーキング メモリにとどまります。
Note
外部アプリケーションがノードをプログラムで追加、削除、更新するなど、エンジンが認識していない外部操作からノードがダーティーとしてマークされることはありません。
次の例は、子エンティティが親エンティティを再アサートするときの動作を説明する簡略化されたシナリオを示しています。 ワーキング メモリに次のような TypedXmlDocument エンティティがあるとします: Parent、Child1、Child2、Child3。
- Parent は最上位レベルの TypedXmlDocument エンティティです。
- 各子には、ExampleField という名前のフィールドが含まれています。なお、この値は 1 (たとえば、
Child1.ExampleField
= 1`)に設定されます。
ルール アクションが子エンティティに対して次の操作を実行するとします:
- Child2 の ExampleField 値が 1 から 0 に更新されます。
- ユーザー コードは、Child3 を削除します。
- ユーザー コードは、NewChild という名前の新しい TypedXmlDocument 子エンティティを Parent に追加します。
次の例は、ワーキング メモリ内のオブジェクトの新しい表現を示しています:
Parent
Child1 // Where Child1.ExampleField = 1
Child2 // Where Child2.ExampleField = 0
NewChild
次に、Parent エンティティを再アサートすると、次の子エンティティの動作が行われます:
- Child2 は、フィールドの更新後にダーティーになったため、再アサートされます。
- Child3 はワーキング メモリから取り消されます。
- NewChild は、ワーキング メモリにアサートされます。
- Child1 は、Parent が再アサートされる前に更新されていないため、ワーキング メモリ内で変更されません。
Update 関数
新しいデータと状態に基づいて、再評価のためにオブジェクトをルール エンジンに再評価するには、Microsoft Rules Composer の Update 関数を使用します。 オブジェクトには、.NET クラス型または、TypedXmlDocument 型を持たせることができます。 Update 関数を使用すると、エンジンのパフォーマンスを向上させ、無限ループ シナリオを防止することもできます。
重要
ルールの再評価の既定の最大ループ数は 2^32 であるため、特定のルールの場合、ルールセットの実行が長時間続く可能性があります。 ループの数を減らすには、ルールセットのバージョンの "Maximum Execution Loop Depth" プロパティを変更します。
.NET オブジェクトを更新する
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Update 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[.NET クラス] を選択します。
[.NET クラス] タブから、クラスを Update 関数の引数にドラッグします。
通常、Assert を使用してルール エンジンの作業メモリに新しいオブジェクトを配置し、Update を使用して、作業メモリ内の既存のオブジェクトを更新します。 新しいオブジェクトをファクトとしてアサートすると、エンジンはすべてのルールの条件を再評価します。 ただし、既存のオブジェクトを更新すると、エンジンは更新されたファクトを使用する条件のみを再評価し、これらの条件が true と評価された場合にアクションを議題に追加します。
たとえば、次の規則があり、ItemA と ItemB という名前のオブジェクトが既にワーキング メモリに存在 とします。
Rule 1 が、ItemA の "Id" プロパティを評価し、ItemB の "Id" プロパティを設定し、変更後、ItemB が再度アサートされます。 ItemB が再アサートされると、エンジンは ItemB を新しいオブジェクトとして扱い、エンジンは述語またはアクションで ItemB を使用するすべてのルールを再評価します。 この動作により、Rule 1 で設定されている ItemB.Id の新しい値に対して、Rule 2がエンジンによって再評価されます。
ルール 1
IF ItemA.Id == 1 THEN ItemB.Id = 2 Assert(ItemB)
Rule 2 は最初の評価で失敗する可能性がありますが、2 番目の評価中に true と評価されます。
ルール 2
IF ItemB.Id == 2 THEN ItemB.Value = 100
オブジェクトをワーキング メモリに再アセンブルする機能により、前方チェーン シナリオでの動作を明示的に制御できます。 ただし、この例では、Rule 1 も再評価されるリアサートによる副作用が明らかになります。 ItemA.Id が変更されていないので、Rule 1 は再び true と評価され、Assert(ItemB) アクションが再度発生します。 その結果、そのルールによって無限ループが発生します。
無限ループを防ぐ
無限ループを作成せずにオブジェクトを再構築できる必要があります。 このようなシナリオを回避するには、Update 関数を使用します。 Reassert 関数と同様に、Update 関数は、ルール アクションによって変更された関連オブジェクト インスタンスに対して Retract および Assert 関数を実行しますが、主な違いは次のとおりです:
議題では、インスタンスの種類が述語ではなくアクションでのみ使用されている場合、ルールのアクションは議題に残ります。
アクションでインスタンス型のみを使用するルールは再評価されません。
その結果、述語のみ、または述語とアクションの両方でインスタンス型を使用するルールが再評価され、ルールのアクションが必要に応じて議題に追加されます。
Update 関数を使用するように前の例を変更すると、Rule 2 の 条件で ItemB が使用されるため、Rule 2 のみをエンジン再評価できます。 ItemB は、Rule 1 * のアクションでのみ使用され、ループ シナリオを排除するため、エンジンでは ルール 1 を再評価されません。
規則 1
IF ItemA.Id == 1
THEN ItemB.Id = 2
Update(ItemB)
規則 2
IF ItemB.Id == 2
THEN ItemB.Value = 100
このように Update 関数を使用しているにもかかわらず、ループ シナリオを作成する可能性は依然として存在します。 たとえば、次のルールがあるとします:
IF ItemA.Id == 1
THEN ItemA.Value = 20
Update(ItemA)
述語は ItemA を使用するため、ItemA で Update が呼び出されたときに、エンジンではルールが再評価されます。 ItemA.Id の値が他の場所で変更されていない場合、Rule 1 は引き続き true として評価され、ItemA で Update を再度呼び出します。
ルール デザイナーでは、このようなループ シナリオが作成されないようにする必要があります。 この問題を解決するための適切なアプローチは、ルールの性質によって異なります。
次の例は、ルールのアクションが初めて実行された後、ルールが再度 true と評価されないようにする ItemA.Value にチェックに追加して、前の例の問題を解決する簡単な方法を示しています。
IF ItemA.Id == 1 and ItemA.Value != 20
THEN ItemA.Value = 20
Update(ItemA)
TypedXmlDocument エンティティを更新する
RuleSet エクスプローラー ウィンドウで、目的のルールを見つけて選択します。
THEN ウィンドウの [アクション] で、Update 組み込み関数をアクションとして追加します。
ファクト エクスプローラー ウィンドウで、[XML スキーマ] を選択します。
[XML スキーマ] タブから、必要なエンティティ ノードを Update 関数の引数にドラッグします。
たとえば、次のようなルールがあるとします:
Rule 1 は、発注書メッセージ内のアイテムの合計数を評価します。
IF 1 == 1 THEN ProcessPO.Order:/Order/Items/TotalCount = (ProcessPO.Order:/Order/Items/TotalCount + ProcessPO:/Order/Items/Item/Count)
Rule 2 では、合計カウントが 10 以上の場合、状態が "承認が必要" に設定されます。
ルール 2
IF ProcessPO.Order:/Order/Items/TotalCount >= 10 THEN ProcessPO.Order:/Order/Status = "Needs approval"
次の発注書メッセージをこのルールセットへの入力として渡すと、TotalCount が 14 であっても、状態が "承認が必要" に設定されていないことに気付づくでしょう。 この動作は、TotalCount 値が 0 の場合にのみ、Rule 2 が開始時にのみ評価されるために発生します。 TotalCount が更新されるたびにルールは評価されません。
<ns0:Order xmlns:ns0="http://ProcessPO.Order">
<Items>
<Item>
<Id>ITM1</Id>
<Count>2</Count>
</Item>
<Item>
<Id>ITM2</Id>
<Count>5</Count>
</Item>
<Item>
<Id>ITM3</Id>
<Count>7</Count>
</Item>
<TotalCount>0</TotalCount>
</Items>
<Status>No approval needed</Status>
</ns0:Order>
TotalCount が更新されるたびにエンジンで条件が再評価されるようにするには、更新されたノード (TotalCount) の親ノード (Items) で Update 関数を呼び出す必要があります。 次のように Rule 1 を変更し、もう一度ルールをテストすると、[状態] フィールドが "承認が必要" に設定されます:
Rule 1 (更新済み)
IF 1 == 1
THEN ProcessPO.Order:/Order/Items/TotalCount = (ProcessPO.Order:/Order/Items/TotalCount + ProcessPO:/Order/Items/Item/Count) AND
Update(ProcessPO.Order:/Order/Items)