基本語法
DataView view = dataTable.DefaultView;
view.RowFilter = "ColumnName = 'Value'"; // 字串值需單引號
// 或
view.RowFilter = "ColumnName = 123"; // 數值無引號
// 或
view.RowFilter = "ColumnName = #2024-03-15#"; // 日期用 #包裹#
常用運算子與函數
| 類別 | 語法 | 範例 |
| 比較 | =, <>, <, >, <=, >= | `Age > 18` |
| 邏輯 | AND, OR, NOT | `Status = 'A' AND Age >= 18` |
| 模糊 | LIKE, NOT LIKE | `Name LIKE 'John%'` (`%` 多字元, `*` 同義, `?` 單字元) |
| 集合 | IN, NOT IN | `Dept IN ('HR','IT','FIN')` |
| 空值 | IS NULL, IS NOT NULL | `Remark IS NULL` |
| 字串函數 | LEN, SUBSTRING, CONVERT | `LEN(Name) > 10` |
| 數學 | +, -, *, /, % | `Price * Qty > 1000` |
| 日期 | #yyyy-MM-dd# | `CreateDate > #2024-01-01#` |
實用範例
// 1. 多條件 AND/OR
view.RowFilter = "Status = 'Active' AND (Category = 'A' OR Category = 'B')";
// 2. 空值或空字串過濾
view.RowFilter = "Email IS NULL OR Email = ''";
// 3. IN 子句 (僅支援常值清單,不支援子查詢)
view.RowFilter = "ProductId IN (1,2,3,5,8)";
// 4. 日期範圍
view.RowFilter = "OrderDate >= #2024-01-01# AND OrderDate <= #2024-12-31#";
// 5. 字串包含 (不分大小寫需自行轉換)
view.RowFilter = "UPPER(Name) LIKE '%JOHN%'";
取得過濾後資料
// 方式一:DataView 直接繫結 UI (GridView 等)
grid.DataSource = view;
// 方式二:轉為新 DataTable (含過濾結果)
DataTable filtered = view.ToTable(); // 正確:只含過濾後列
// DataTable filtered = view.Table; // 錯誤:回傳原始未過濾 DataTable
// 方式三:逐列處理
foreach (DataRowView rowView in view)
{
DataRow row = rowView.Row;
// 處理...
}
重要限制與陷阱
| 限制 | 說明 | 替代方案 |
| 不支援 <> 或 != | RowFilter 語法無不等於運算子 | 用 `NOT (Col = 'Val')` 或 `Col IN ('A','B')` 排除法 |
| 不支援子查詢 | `Col IN (SELECT ...)` 會報錯 | 先查詢結果建立清單,用 `IN (val1,val2...)` |
| 單一 RowFilter | 同一 DataView 只能設一個 RowFilter,後設定會覆蓋 | 用 AND/OR 合併條件,或建立多個 DataView |
| 不修改原 DataTable | RowFilter 僅影響 View,原 Table 資料不變 | 需永久刪除請用 `dt.Rows.Remove(row)` |
| 大小寫敏感 | 字串比較預設區分大小寫 | 用 `UPPER(Col) = 'VALUE'` |
| 效能 | 大量資料 (>10萬列) RowFilter 較慢 | 改用 LINQ to DataTable 或資料庫端過濾 |
效能優化建議
- 頻繁變更過濾條件時,建議建立
DataView 快取,避免重複 `DefaultView` 建立開銷。
- 靜態過濾條件可在 `DataTable.Select(filter)` 直接取得 `DataRow[]`,一次性查詢較快。
- 超大資料集請在資料庫層完成過濾,勿載入記憶體再篩選。
參考資源
原文連結:https://www.bianceng.cn/Programming/csharp/201410/45574.htm