斷言 是將物件實例新增至商務規則引擎工作記憶體的程式。 引擎根據實例類型所定義的條件和動作,透過比對、衝突解決和動作三個階段來處理每個實例。
下列主題描述針對不同事實類型使用 Assert 函式所產生的行為。
.NET 物件
每個物件皆會以個別實例的形式加入工作記憶體中。 這表示每一個引用物件類型的述詞都會用來分析該實例(例如,IF Object.Property = 1)。 它也可供參考型別的規則動作使用,視規則條件的結果而定。
請考慮下列範例。
規則 1
IF A.Value = 1
THEN A.Status = "good"
規則 2
IF B.Value = 1
THEN A.Status = "good"
在規則 1 中,只有值為 1 的 A 實例才會更新其 Status 屬性。 不過,在規則 2 中,如果條件評估為 true,則 A 的所有實例都會更新其狀態。 事實上,如果有多個 B 實例,則每次條件評估為 true 時,A 實例都會更新。
若要在規則中斷言 .NET 物件,您可以將內建 Assert 函式新增為規則的動作。 請注意,規則引擎具有 CreateObject 函式,但不會顯示為商務規則編輯器中的個別函式。 其調用是透過將您欲建立物件的建構函式方法從 [Facts Explorer] 的 .NET 類別檢視中拖曳到動作窗格來完成。 然後,商務規則撰寫器會將建構函式方法轉譯為規則定義中的 CreateObject 呼叫。
TypedXmlDocument
當 TypedXmlDocument 被斷言時,業務規則引擎會根據規則中定義的選擇器創建子 TypedXmlDocument 實例。
選取器和欄位都是 XPath 運算式。 您可以將選取器視為隔離 XML 檔案節點的一種方式,而欄位則用來識別選取器中的特定項目。 所有在單一選取器內的欄位都會被引擎組合成一個物件。 當您在 [事實總管] 的 XML 架構 標籤下選取節點時,業務規則編輯器會自動填入所有節點的 XPath 選取器 屬性,以及任何不包含子節點的節點的 XPath 欄位 屬性。 或者,如有必要,您可以為 XPath 選取器和 XPath 字段輸入自己的 XPath 表達式。
如果選取器匹配到 XML 文件的多個部分,則會將此類型的多個物件置入或從規則引擎的工作記憶體中移除。 假設您有下列 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 的兩個項目和 Jane 的兩個項目。
<root>
<order customer="Joe">
</order>
<order customer="Jane">
</order>
</root>
每個物件都有三個字段的存取權:@name、 @quantity和 @cost。 由於該物件是對原始文件的參照,因此您可以引用父欄位(例如 "../@customer")。
您可以在同一份檔中使用多個選取器。 這可讓您檢視檔的不同部分(例如,如果有一個區段是訂單,另一個區段包含出貨位址)。 不過,請記住,所建立的物件是由建立它們的 XPath 字串所定義。 使用不同的 XPath 運算式,即使解析為相同的節點,也會生成獨特的 TypedXmlDocument。
規則引擎原生支援基本 .NET 純量類型,以及參考型別的物件。 XML 檔基本上是文字,但根據建立規則時指定的類型,域值可能屬於任何類型。 此外,因為欄位是 XPath 運算式,所以可能會傳回一組節點,這種情況下,會將集合中的第一個項目當作值來使用。
在幕後,規則引擎可以透過 XmlConvert 函式,將文字域值轉換成任何一個支援的類型。 您可以藉由在 Business Rule Composer 中設定類型來指定這個。 如果轉換不可行,會拋出例外狀況。 bool 和 double 類型只能擷取為各自的類型、字串或物件。
TypedDataTable
在宣告 TypedDataTable 時,DataTable 中包含的所有 DataRows 都會自動在引擎中被宣告為 TypedDataRows。 每當數據表或數據表數據行當做規則自變數使用時,就會根據個別 TypedDataRows 評估表達式,而不是針對 TypedDataTable 評估。
例如,假設您已根據 「Customers」 資料表建置下列規則:
IF Northwind.Customers.CustomerID = 001
THEN Northwind.Customers.ContactTitle = "Purchasing Manager"
備註
若要針對資料庫數據表建置規則,您必須使用 數據表/數據列 作為資料庫系結類型。
假設您將下列 DataTable 連同三個 DataRows 作為 TypedDataTable 插入到引擎中。
| 客戶編號 | 聯絡標題 |
|---|---|
| 001 | 物料管理員 |
| 002 | 物料管理員 |
| 003 | 物資管理員 |
引擎會插入三個 TypedDataRows:001、002 和 003。
每個 TypedDataRow 都會根據規則獨立評估。 第一個 TypedDataRow 符合規則條件,而第二個兩個失敗。 結果如下所示。
| 客戶編號 | 聯絡人職稱 |
|---|---|
| 001 | 購買管理員 |
| 002 | 供應職員 |
| 003 | 物料管理員 |
備註
TypedDataRows 也可以直接插入到引擎中。 這些處理方式與先前所述相同。
DataSetName.DataTableName 會被視為唯一標識符。 因此,如果第二個 TypedDataTable 被宣告為具有相同的 DataSet 名稱和 DataTable 名稱,它將取代第一個 TypedDataTable。 所有與第一個 TypedDataTable 相關聯的 TypedDataRow 都會被收回,而第二個 TypedDataTable 被確認。
DataConnection
如同 TypedDataTable,將數據表或數據行拖曳為商務規則撰寫器中的規則自變數,會產生根據傳回的 TypedDataRow 所建置的規則,而不是 DataConnection 本身。
假設已建立下列規則,並斷言 DataConnection 包含一個至 Northwind.Customers 的 SqlConnection:
IF Northwind.Customers.CustomerID = 001
THEN Northwind.Customers.ContactTitle = "Purchasing Manager"
當引擎評估 TypedDataTable 區段中所使用的規則時,它會動態建置看起來如下的查詢:
SELECT *
FROM Northwind.Customers
WHERE CustomerID = 1
因為資料庫中只有一個資料列符合此準則,因此只會建立一個 TypedDataRow ,並插入至引擎以進行進一步處理。
已確認實體和實例類型的摘要
下表摘要說明各種類型的判斷提示行為,其中顯示針對每個判斷提示實體在引擎中建立的結果實例數目,以及套用至每個實例的型別來識別它們。
| 實體 | 判斷提示的實例數目 | 實例類型 |
|---|---|---|
| .NET 物件 | 1 (物件本身) | 完整限定的 .NET 類別 |
| TypedXmlDocument | 1-N 型別化 XML 文件:根據所建立的選擇器綁定和文件內容 | 文件類型.選擇器 |
| TypedDataTable | 1-N TypedDataRow(個) DataTable 中每個 DataRow 各一個 |
資料集名稱.資料表名稱 |
| 類型化資料列 | 1 (TypedDataRow 斷言) | DataSetName.DataTableName |
| DataConnection | 1-N (查詢 DataConnection 所傳回的每個 TypedDataRow 各一個) | DataSetName.DataTableName |