Linq已經出來一段時間了,最近剛好有個測試會用到DataTable去過濾資料,不過這個過濾條件是動態的,除了使用Dynamic Linq,或許用Func就可以做到.
Linq已經出來一段時間了,最近剛好有個測試會用到DataTable去過濾資料,不過這個過濾條件是動態的,除了使用Dynamic Linq,或許用Func就可以做到.
這次使用Linq去過濾的測試資料如下:
DataTable dt = new DataTable();
private void Form1_Load(object sender, EventArgs e)
{
//新增測試資料
dt.Columns.Add("UserName");
dt.Rows.Add(new object[] { "Andy" });
dt.Rows.Add(new object[] { "Bill" });
dt.Rows.Add(new object[] { "Chanel" });
dt.Rows.Add(new object[] { "David" });
dt.Rows.Add(new object[] { "Elsa" });
dt.Rows.Add(new object[] { "Frank" });
dataGridView1.DataSource = dt;
}
這個測試資料呈現就會如下所示 :
接下來就是在輸入過濾條件後,按下Filter,要怎麼樣去依條件來過濾資料.
private void button1_Click(object sender, EventArgs e)
{
if (dt.Rows.Count == 0) return;
if (txtFilter.Text.Trim().Length == 0)
{
dataGridView1.DataSource = dt;
}
else
{
//將輸入的過濾條件轉為小寫並去除前後空白,再用每個字中間的空白拆到string array
string[] ary = txtFilter.Text.ToLower().Trim().Split(' ');
IEnumerable<DataRow> qry = from d in dt.AsEnumerable()
where GetResult(d, ary)//使用Func的方式去判斷條件
select d;
if (qry.Count<DataRow>() == 0)
MessageBox.Show("找不到符合資料");
else
dataGridView1.DataSource = qry.CopyToDataTable<DataRow>();//顯示到DataGridView上
}
}
Func<DataRow, string[], bool> GetResult = delegate(DataRow dr, string[] str)
{
foreach (string s in str)
{
//將DataRow的UserName值轉為小寫去比較,如果存在就回傳true
if (dr.Field<string>("UserName").ToLower().Contains(s)) return true;
}
return false;
};
所以輸入Andy按下Filter,就只會過濾出Andy那筆
如果是輸入Andy David,當然就只會出現這兩個人.
參考 :
MSDN Func<(Of <(T1, T2, TResult>)>) 委派
原始碼 :