Aktualisierungsfunktion
Wenn die Update-Funktion ein -Objekt aufgerufen wird, wird das Objekt basierend auf den neuen Daten und dem neuen Zustand in die Engine eingefügt, um erneut ausgewertet zu werden. Das Objekt kann vom Typ TypedXmlDocument oder .NET-Klasse oder DataConnection oder TypedDataTable sein.
Sie können auch die Update-Funktion verwenden, um die Engine-Leistung zu verbessern und Endlosschleifenszenarien zu verhindern, wie in diesem Thema beschrieben.
In der Regel verwenden Sie Assert , um ein neues Objekt im Arbeitsspeicher der Regel-Engine zu platzieren, und verwenden Sie Update , um ein bereits vorhandenes Objekt im Arbeitsspeicher zu aktualisieren. Wenn Sie ein neues Objekt bestätigen, werden die Bedingungen in allen Regeln ausgewertet. Wenn Sie ein vorhandenes Objekt aktualisieren, werden nur Bedingungen erneut ausgewertet, die den aktualisierten Fakt verwenden, und Aktionen werden der Agenda hinzugefügt, wenn diese Bedingungen als Wahr ausgewertet werden.
Die beiden folgenden Regeln dienen als Beispiel. Angenommen, die Objekte ItemA und ItemB sind bereits im Arbeitsspeicher vorhanden. Regel 1 wertet die Id-Eigenschaft für ItemA aus, legt die Id-Eigenschaft für ItemB fest und überprüft dann ItemB nach der Änderung erneut. Wenn ItemB erneut überprüft wird, wird es als neues Objekt behandelt, und die Engine wertet alle Regeln neu aus, die Objekt ItemB in den Prädikaten oder Aktionen verwenden. Dadurch wird sichergestellt, dass Regel 2 anhand des neuen Werts von ItemB.Id neu ausgewertet wird, wie in Regel 1 festgelegt. Regel 2 ist bei der ersten Auswertung möglicherweise fehlgeschlagen, wird aber bei der zweiten Auswertung als wahr ausgewertet.
IF ItemA.Id == 1
THEN ItemB.Id = 2
Assert(ItemB)
IF ItemB.Id == 2
THEN ItemB.Value = 100
Dank der Möglichkeit, Objekte erneut zu bestätigen und in den Arbeitsspeicher zu übergeben, hat der Benutzer direkten Einfluss auf das Verhalten in Vorwärtsverkettungsszenarien. Ein Nebeneffekt der erneuten Übergabe in diesem Beispiel besteht allerdings darin, dass Regel 1 ebenfalls neu ausgewertet wird. Da ItemA.Id nicht geändert wurde, wird Regel 1 erneut als true ausgewertet, und die Assert(ItemB) -Aktion wird erneut ausgelöst. In der Folge erstellt die Regel eine Endlosschleife.
Hinweis
Die standardmäßige maximale Schleifenanzahl der Neuauswertung von Regeln beträgt 2^32. Bei bestimmten Regeln kann die Richtlinienausführung lange dauern. Sie können die Anzahl verringern, indem Sie die Maximale Ausführungsschleifentiefe der Richtlinienversion anpassen.
Sie müssen in der Lage sein, Objekte erneut zu erstellen, ohne Endlosschleifen zu erstellen, und die Funktion Update bietet diese Funktion. Wie bei einer erneuten Überprüfung führt die Update-FunktionRetract und Assert der zugeordneten Objektinstanzen aus, die von Regelaktionen geändert wurden, aber es gibt zwei wichtige Unterschiede:
Aktionen in der Agenda für Regeln, bei denen der Instanztyp nur in den Aktionen (nicht den Prädikaten) verwendet wird, verbleiben in der Agenda.
Regeln, die nur den Instanztyp in den Aktionen verwenden, werden nicht neu ausgewertet.
Daher werden Regeln, die die Instanztypen nur in den Prädikaten oder sowohl in den Prädikaten als auch den Aktionen verwenden, neu ausgewertet. Ihre Aktionen werden der Agenda gegebenenfalls hinzugefügt.
Wenn Sie das vorherige Beispiel so ändern, dass die Update-Funktion verwendet wird, wird sichergestellt, dass nur Regel 2 neu ausgewertet wird, da ItemB in der Bedingung von Regel 2 verwendet wird. Regel 1 wird nicht neu ausgewertet, da ItemB nur in den Aktionen von Regel 1 verwendet wird, wodurch das Schleifenszenario beseitigt wird.
IF ItemA.Id == 1
THEN ItemB.Id = 2
Update(ItemB)
IF ItemB.Id == 2
THEN ItemB.Value = 100
Es ist jedoch nach wie vor möglich, Schleifenszenarien zu erstellen. Betrachten Sie z. B. folgende Regel.
IF ItemA.Id == 1
THEN ItemA.Value = 20
Update(ItemA)
Da ItemA im Prädikat verwendet wird, wird es neu ausgewertet, wenn Update für ItemA aufgerufen wird. Wenn der Wert von ItemA.Id an anderer Stelle nicht geändert wird, wird in Regel 1 weiterhin true ausgewertet, sodass Update erneut für A aufgerufen wird. Der Regel-Designer muss sicherstellen, dass solche Schleifenszenarien nicht erstellt werden.
Welches Verfahren geeignet ist, wird von der Art der Regeln bestimmt. Im Folgenden finden Sie einen einfachen Mechanismus, mit dem sich das Problem im vorangegangenen Beispiel lösen lässt.
Die Update-Funktion kann im Business Rule Composer mit einem Verweis auf die -Klasse verwendet werden, wie bei den Funktionen Assert, Retract oder RetractByType .
IF ItemA.Id == 1 and ItemA.Value != 20
THEN ItemA.Value = 20
Update(ItemA)
Durch das Hinzufügen der Überprüfung für ItemA.Value wird verhindert, dass Regel 1 erneut auf TRUE ausgewertet wird, nachdem die Aktionen von Regel 1 zum ersten Mal ausgeführt wurden.
Die beiden folgenden Regeln dienen als Beispiel. Die folgenden Annahmen gelten: Regel 1 wird zur Summe der Posten in einer Bestellungsnachricht ausgewertet, und Regel 2 legt den Status auf Genehmigung erforderlich fest, wenn die Gesamtsumme größer oder gleich 10 ist.
IF 1 == 1
THEN ProcessPO.Order:/Order/Items/TotalCount = (ProcessPO.Order:/Order/Items/TotalCount + ProcessPO:/Order/Items/Item/Count)
IF ProcessPO.Order:/Order/Items/TotalCount >= 10
THEN ProcessPO.Order:/Order/Status = "Needs approval"
Wenn Sie die folgende Bestellungsmeldung als Eingabe an diese Richtlinie übergeben, stellen Sie fest, dass die status nicht auf "Genehmigung erforderlich" festgelegt ist, obwohl die Gesamtanzahl der Artikel 14 beträgt. Dies liegt daran, dass die Regel2 nur am Anfang ausgewertet wird, wenn der Wert des Felds TotalCount 0 ist, und die Regel nicht jedes Mal ausgewertet wird, wenn die Gesamtzahl der verfügbaren Gesamtanzahl aktualisiert wird. Damit die Bedingungen bei jeder Aktualisierung des TotalCount-Objekts neu ausgewertet werden, müssen Sie die Update-Funktion auf dem übergeordneten Knoten (Items) des geänderten Knotens (TotalCount) aufrufen. Wenn Sie Regel 1 wie unten gezeigt ändern und ein weiteres Mal testen, sollte der Wert des Feld Status auf Genehmigung erforderlich festgelegt worden sein.
<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>
Die geänderte Regel 1 lautet wie folgt:
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)
Wenn Update für eine TypedDataTable aufgerufen wird, wird Update von der Engine für alle zugeordneten TypedDataRows aufgerufen. Das Update kann auch für einzelne TypedDataRows aufgerufen werden.
Das Aktualisieren einer DataConnection wird nicht unterstützt. Verwenden Sie stattdessen Assert .