當叫用 Update 函式時,對象會根據新的數據和狀態重新置入引擎中,以便重新評估。 對象的類型可以是 TypedXmlDocument 或 .NET 類別或 DataConnection 或 TypedDataTable。
您也可以使用 Update 函式來改善引擎效能,並防止無休止的迴圈案例,如本主題所述。
一般而言,您可以使用 Assert 將新物件放在規則引擎的工作記憶體中,並使用 Update 來更新工作記憶體中已經存在的物件。 當您建立新的物件時,所有規則中的條件都會被評估。 當您更新現有的物件時,只有使用已更新事實的條件會被重新評估,如果這些條件被評估為成立,則會將這些動作新增至議程。
在 .NET 事實上使用 Update 函式
以下列兩個規則為例。 假設 ItemA 和 ItemB 物件已存在於工作記憶體中。 規則 1 會評估 ItemA 上的 Id 屬性、在 ItemB 上設定 Id 屬性,然後在變更之後重新評估 ItemB。 重新評估 ItemB 時,它會被視為新的物件,而引擎會重新評估在述詞或動作中使用 物件 ItemB 的所有規則。 這可確保規則 2 會根據規則 1 中所設定的新值 重新評估 ItemB.Id。 規則 2 在第一次評估時可能失敗,但在第二次評估時評估為 true 。
規則 1
IF ItemA.Id == 1
THEN ItemB.Id = 2
Assert(ItemB)
規則 2
IF ItemB.Id == 2
THEN ItemB.Value = 100
重新調回物件至工作記憶體的能力,可以讓使用者在前向推理情境中明確控制行為。 不過,在此範例中重申後的一個副作用是,規則 1 也會被重新檢討。 因為 ItemA.Id 未變更,規則 1 再次評估為 true,然後 Assert(ItemB) 動作再次觸發。 因此,規則會建立無休止的循環狀況。
備註
重新評估規則的預設最大循環計數為 2^32。 針對特定規則,原則執行可能會持續很長一段時間。 您可以藉由調整原則版本的最大 執行迴圈深度 屬性來減少計數。
您必須能夠在不建立無休止的循環的情況下重新確認物件,Update 函式提供此功能。 如同重申,更新功能會執行相關聯對象實例的撤回和斷言,這些對象實例已被規則動作更改,但有兩個主要區別:
實例類型只用於行動(而非述詞)的規則議程上的動作將保留在議程上。
只使用動作中實例類型的規則將不會重新評估。
因此,使用實例類型的規則,不論只應用於述詞中,或同時應用於述詞和動作中,將會被重新評估,並將其動作適當地新增至議程。
將上述範例變更為使用 Update 函式可確保只有規則 2 會重新評估,因為 ItemB 用於規則 2 的條件。 規則 1 不會重新評估,因為 ItemB 只會用於規則 1 的動作中,以消除迴圈案例。
規則 1
IF ItemA.Id == 1
THEN ItemB.Id = 2
Update(ItemB)
規則 2
IF ItemB.Id == 2
THEN ItemB.Value = 100
不過,仍然可以建立迴圈案例。 例如,請考慮下列規則。
規則 1
IF ItemA.Id == 1
THEN ItemA.Value = 20
Update(ItemA)
因為 ItemA 是在述詞中使用,所以會在 ItemA 上呼叫 Update 時重新評估。 如果 ItemA.Id 的值未在其他地方變更,規則 1 會繼續評估為 true,導致 A 再次呼叫 Update 。規則設計工具必須確保不會建立這類迴圈案例。
這的適當方法會根據規則的性質而有所不同。 以下是解決上述範例中問題的簡單機制。
Update 函式可用於 Business Rule Composer 中,類似於 Assert、Retract 或 RetractByType 函式,均需參考類別。
規則 1
IF ItemA.Id == 1 and ItemA.Value != 20
THEN ItemA.Value = 20
Update(ItemA)
在 ItemA.Value 上新增檢查可防止第一次執行規則1的動作之後,再次評估為 true 。
在 XML 資料中使用更新函數
以下列兩個規則為例。 假設是這樣。 規則 1 會評估採購單訊息中專案的總計數,如果總計數大於或等於 10,rule2 會將狀態設定為「需要核准」。
規則 1
IF 1 == 1
THEN ProcessPO.Order:/Order/Items/TotalCount = (ProcessPO.Order:/Order/Items/TotalCount + ProcessPO:/Order/Items/Item/Count)
規則 2
IF ProcessPO.Order:/Order/Items/TotalCount >= 10
THEN ProcessPO.Order:/Order/Status = "Needs approval"
如果您將下列採購單(PO)訊息作為此政策的輸入,您會注意到狀態並未設置為「需要核准」,即使項目總數為 14。 這是因為只有在 TotalCount 字段的值是 0 時才會評估 rule2,而在每次更新總可用計數時,rule2 並不會被重新評估。 若要在每次更新 TotalCount 時重新評估條件,您必須在修改後的節點 (TotalCount) 所屬的父節點 (Items) 上呼叫 Update 函式。 如果您變更 Rule1,如下所示,並再測試一次,您應該會看到 [狀態] 欄位的值設定為 [需要核准]。
<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>
變更 的規則 1 如下所示:
規則 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)
在資料庫資料上使用更新函數
TypedDataTable
如果在 TypedDataTable 上呼叫 Update,則引擎會在所有相關聯的 TypedDataRows 上呼叫 Update。 您也可以 在個別 TypedDataRows 上呼叫更新。
DataConnection
不支援 DataConnection 的更新。 請改用 Assert 。