BQL 解析和驗證
任何 Acumatica 應用程式開發人員都花費大量時間編寫 BQL 程式碼。與此同時,並非所有人都知道 BQL 型別如何在幕後工作的基本細節。
BQL 的核心是兩個關鍵方法:Parse()
和 Verify()
,由 IBqlCreator
介面宣告。大多數常用的 BQL 型別,如 Where<>
,And<>
,Or<>
等,都來自這個介面。
應該承認,這些方法歷史上堅持的名稱不是很具描述性。可以說更好的替代名稱是 PrepareCommandText
和 Evaluate
。
解析
public void Parse(
PXGraph graph,
List<IBqlParameter> pars,
List<Type> tables,
List<Type> fields,
List<IBqlSortColumn> sortColumns,
StringBuilder text,
BqlCommand.Selection selection)
Parse()
的唯一目的是將 BQL 轉換為要傳送到 DBMS 的 SQL 命令。因此,此方法接受表示當前正在構造的 SQL 命令的 StringBuilder
引數,BQL 建立者將其附加到其自身的 SQL 文字表示形式。
例如,And<>
謂詞的 Parse()
方法會將 AND
附加到命令文字,並遞迴請求所有巢狀 BQL 建立者的翻譯。
特別是,And<ARRegister.docType, Equal<ARDocType.invoice>>
將轉化為像 "AND "ARRegister.DocType = 'AR'"
這樣的東西。
校驗
public void Verify(
PXCache cache,
object item,
List<object> pars,
ref bool? result,
ref object value)
與 Parse()
相比,Verify()
純粹在應用程式級別執行。
給定記錄(例如,ARRegister
物件),它可用於計算其上的表示式,包括計算公式和評估條件。
result
引數用於儲存布林條件評估結果。它主要由謂詞 BQL 建立者使用,例如 Where<>
。
value
引數用於儲存表示式計算結果。例如,BQL Constant<string>
的 value
是該常量的字串表示。
大多數情況下,BQL 建立者會影響結果或值,但很少會影響兩者。
Verify()
方法的一個值得注意的用法是靜態 BqlCommand.Meet()
方法,由 PXCache
用來確定給定項是否滿足 BQL 命令:
public bool Meet(PXCache cache, object item, params object[] parameters)
{
List<object> pars = new List<object>(parameters);
bool? result = null;
object value = null;
try {
Verify(cache, item, pars, ref result, ref value);
}
catch (SystemException ex) {
throw new PXException(String.Format("BQL verification failed! {0}", this.ToString()), ex);
}
return result == null || result == true;
}
結論
BQL 建立者的真正力量和美麗在於,它們中的大多數可以在資料庫和應用程式級別使用,從而實現 Acumatica 的快取合併機制,併為程式碼可重用性提供了很好的機會。
例如,當你從資料庫中選擇記錄時,BQL 命令的 Where<>
子句:
- 將提供
Parse()
在命令準備期間將自身轉換為 SQL 文字。 - 將在快取合併期間提供
Verify()
以確定哪些專案已經駐留在快取Meet()
Where<>
子句條件中,以便將此類快取專案包含到結果集中。