System.Data.DataTable 內建的 Compute 與 DataColumn.Expression 提供強大的離線運算能力,可執行聚合、字串處理、型別轉換、條件判斷、甚至父子關聯表運算,大幅減少資料庫往返與複雜 SQL 撰寫。
Compute(expression, filter) 接受運算式與篩選條件,回傳標量結果。支援聚合函數:
Count、Sum、Avg、Min、MaxStDev(標準差)、Var(變異數)DataTable table = new DataTable();
table.Columns.Add("id", typeof(string));
table.Columns.Add("value", typeof(int));
// 填入 1~10 測試資料...
object result = table.Compute("sum(value)", ""); // 55
result = table.Compute("avg(value)", ""); // 5
result = table.Compute("max(value)/sum(value)", ""); // 0.1818...
result = table.Compute("count(id)", "true"); // 10 (篩選有效)
常數運算不需資料列:table.Compute("1+1", "") 回傳 2。注意 abs(1) 會回傳 null,其他數學函數可能拋出例外。
將 DataColumn.Expression 設定為運算式,該欄位自動成為計算欄位,逐列評估:
column.Expression = "len(id)"; // 長度
column.Expression = "substring(id, 3, len(id)-2)"; // 子字串,起始位置從 1 算起
column.Expression = "trim(' ' + id + ' ')"; // 去除空白
column.Expression = "convert(substring(id,3,len(id)-2), 'System.Int32') * 1.6";
// IIF(條件, 真值, 假值) - 相當於 SQL CASE WHEN
column.Expression = "iif(value > 5, 1000, 2000)";
// 巢狀條件
column.Expression = "iif(value > 5, 1000, iif(id like '%1', 4000, 2000))";
// LIKE、IN 運算子
column.Expression = "iif(id like '%1', 1000, 2000)";
column.Expression = "iif(id not in ('id1'), 1000, 2000)";
// 空值處理 - 相當於 ISNULL
column.Expression = "isnull(value, 10)";
// 佔總和百分比
column.Expression = "value / sum(value)";
// 與最大值差距
column.Expression = "max(value) - value";
透過 DataRelation 建立關聯,使用 child(關聯名).欄位 存取子表資料:
DataRelation relation = new DataRelation("relation",
parentTable.Columns["id"], childTable.Columns["id"]);
ds.Relations.Add(relation);
// 子表筆數
column.Expression = "count(child(relation).value)";
// 父表值佔子表總和比例
column.Expression = "value / sum(child(relation).value)";
// 庫存與訂單差額
column.Expression = "iif(value - sum(child(relation).value) > 0, 0, value - sum(child(relation).value))";
Compute 僅支援彙總函數,不可用於逐列運算善用 DataTable 離線運算,能將商務邏輯前移至用戶端或中間層,降低資料庫負載並提升開發彈性。