如何建立事實擷取器
「事實擷取器」 (Fact Retriever) 是一種元件,在其執行期間,可用於將長期事實的執行個體判斷提示到原則。 您可以實作 IFactRetriever 介面,並設定原則版本,以在執行時間使用此實作來帶入長期事實實例。 如果針對該特定版本設定事實擷取器,原則版本會在每個執行循環叫用事實擷取器實作的 UpdateFacts 方法。
您可以選擇性地在事實擷取器元件上實作 IFactRemover 介面。 規則引擎會在處置原則時叫用IFactRemover介面的UpdateFactsAfterExecution方法。 這樣便會提供您進行任何後執行工作的機會。例如認可任何資料庫變更,或是從規則引擎的工作記憶體中撤回任何物件執行個體。
指定原則的事實擷取器
您可以使用下列程式碼以便將規則集設定為使用 "MyAssembly" 組件中的 "Retriever" 類別作為事實擷取器。
RuleEngineComponentConfiguration fr = new RuleEngineComponentConfiguration("MyAssembly", "Retriever");
RuleSet rs = new RuleSet("ruleset");
// associate the execution configuration with a ruleset
RuleSetExecutionConfiguration rsCfg = rs.ExecutionConfiguration;
rsCfg.FactRetriever = factRetriever;
注意
如果您指定如 MyAssembly 的簡單組件名稱做為 RuleEngineComponentConfiguration 建構函式的第一個參數,BizTalk 規則引擎就會假設它是私用組件,並會在您的應用程式資料夾中尋找該組件。 如果您指定完整元件名稱 ,例如 MyAssembly、Version=1.0.0.0、Culture=neutral、PublicKeyToken=a310908b42c024fe,規則引擎會假設它是共用元件,並在全域組件快取中尋找元件, (GAC) 。 您可以在 找到簡單和完整元件名稱 https://go.microsoft.com/fwlink/?LinkId=64535 的定義。
您可以利用必要的應用程式特有邏輯將事實擷取器設計為連接到必要資料來源,判斷提示資料為長期事實到引擎中,並指定用於重新整理或判斷提示長期事實的新執行個體到引擎的邏輯。 直到更新前,最初判斷提示到引擎進而快取的值將用於後續的執行循環。 事實擷取器實作會傳回類似權杖的物件,並可與 factsHandleIn 物件一起使用,以判斷是否更新現有的事實或判斷新事實。 當原則版本第一次呼叫其事實擷取器時, factsHandleIn 物件一律為 Null,然後在事實擷取器執行之後接受傳回物件的值。
請注意,對於相同的規則引擎執行個體,長期事實只需要判斷提示一次。 例如,當您在協調流程中使用 呼叫規則 圖形時,原則實例會移至內部快取中。 此時,會撤回所有短期事實而保留長期事實。 若再次呼叫相同的原則,無論是相同的協調流程執行個體或相同主控件內不同的協調流程執行個體,都會從快取中擷取此原則執行個體並重複使用。 在部分批次處理實例中,會建立相同原則的數個原則執行個體。 若建立新原則執行個體,則必須確保判斷提示正確的長期事實。
此外,您需要撰寫自訂程式碼以實作下列策略:
瞭解何時更新長期事實
應追蹤哪個規則引擎執行個體使用的哪個長期事實
以下範例程式碼顯示使用不同繫結類型的不同事實擷取器實作,這些實作與 [MyPolicy] 相關聯以判斷提示 [MyTableInstance] 為長期事實。
DataTable 繫結
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
SqlDataAdapter dAdapt = new SqlDataAdapter();
dAdapt.TableMappings.Add("Table", "CustInfo");
SqlConnection conn = new SqlConnection("Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;");
conn.Open();
SqlCommand myCommand = new SqlCommand("SELECT * FROM CustInfo", conn);
myCommand.CommandType = CommandType.Text;
dAdapt.SelectCommand = myCommand;
DataSet ds = new DataSet("Northwind");
dAdapt.Fill(ds);
TypedDataTable tdt = new TypedDataTable(ds.Tables["CustInfo"]);
engine.Assert(tdt);
factsHandleOut = tdt;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
DataRow 繫結
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
SqlDataAdapter dAdapt = new SqlDataAdapter();
dAdapt.TableMappings.Add("Table", "CustInfo");
SqlConnection conn = new SqlConnection("Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;");
conn.Open();
SqlCommand myCommand = new SqlCommand("SELECT * FROM CustInfo", conn);
myCommand.CommandType = CommandType.Text;
dAdapt.SelectCommand = myCommand;
DataSet ds = new DataSet("Northwind");
dAdapt.Fill(ds);
TypedDataTable tdt = new TypedDataTable(ds.Tables["CustInfo"]);
// binding to the first row of CustInfo table
TypedDataRow tdr = new TypedDataRow(ds.Tables["CustInfo"].Rows[0],tdt);
engine.Assert(tdr);
factsHandleOut = tdr;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
以下範例程式碼示範如何在事實擷取器實作中判斷提示 .NET 和 XML 事實。
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
if (factsHandleIn == null)
{
//create .NET object instances
bookInstance = new Book();
magazineInstance = new Magazine();
//create an instance of the XML object
XmlDocument xd = new XmlDocument();
//load the document
xd.Load(@"..\myXMLInstance.xml");
//create and instantiate an instance of TXD
TypedXmlDocument doc = new TypedXmlDocument("mySchema",xd1);
engine.Assert(bookInstance);
engine.Assert(magazineInstance);
engine.Assert(doc);
factsHandleOut = doc;
}
else
factsHandleOut = factsHandleIn;
return factsHandleOut;
}
}
}
DataConnection 繫結
using System;
using System.Xml;
using System.Collections;
using Microsoft.RuleEngine;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace MyBizTalkApplication.FactRetriever
{
public class myFactRetriever:IFactRetriever
{
public object UpdateFacts(RuleSetInfo rulesetInfo, Microsoft.RuleEngine.RuleEngine engine, object factsHandleIn)
{
object factsHandleOut;
{
string strCmd = "Initial Catalog=Northwind;Data Source=(local);Integrated Security=SSPI;";
SqlConnection conn = new SqlConnection(strCmd);
DataConnection dc = new DataConnection("Northwind", "CustInfo", conn);
engine.Assert(dc);
factsHandleOut = dc;
}
return factsHandleOut;
}
}
}
請注意,當從事實擷取器提供時,應該一律重新建構 DataConnections,如上述程式碼範例所示。 引擎實例會使用 DataConnection 根據規則條件來查詢資料庫,而查詢傳回的任何資料列都會判斷提示到引擎的工作記憶體中 做為 TypedDataRows。 重新判斷提示 DataConnection ,可確保先前引擎執行的資料列已自記憶體中清除。
事實上,透過事實擷取器判斷 DataConnection 有一些優點,不同之處在于它提供將資料來源外部化的方式。