用Linq来查询DataTable是非常方便,效率也是很高的。下面是一个示例代码。
//Define a data table and top up data with null in Age Field
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Columns.Add("Height", typeof(float));
dt.Rows.Add(1, "Yvon", 23, 168.5);
dt.Rows.Add(2, "Weow", DBNull.Value, 178.5);
dt.Rows.Add(3, "Jim", null, 166.5);
dt.Rows.Add(4, "Phili", 65, 186.5);
dt.Rows.Add(5, "Eva", 18, 159.0);
//Linq to select Age value which Age>5
var q = from dr in dt.AsEnumerable()
where dr.Field<int>("Age")> 5
select dr.Field<int>("Age");
//Print out selected ages
foreach(int a in q)
{
textBox1.Text += a.ToString() + ", ";
}
上面的Linq代码是我们非常常用的,但是Datatable里面如果有空值(DBNull), DataTable的设计就是可以接受空值的(数据在DataTable中存储实际为Object类型)。
但是我们的Linq代码由于指定了类型,在运行的时候就会出错,提示不能把DBNull转为int类型 (这里我们可以发现虽然我们用dr.Field<int>("age")指定了类型,其实Linq在查询的时候会自动做一次类型转换)。
如果我们需要在Linq中指定数据类型,那我们怎么才能把空值滤除掉了,我们是不能对比dr.Field<int>("age")!=DBNull.Value的,因为类型不一样。请参考下面的代码。(dr["Age"]用了类似与Datatable行,列取值的方法来调用,这时候数据其实是Object类型,所以可以跟DBNull比较。
//Linq to select Age value which Age>5
var q = from dr in dt.AsEnumerable()
where dr["Age"]!=DBNull.Value && dr.Field<int>("Age")> 5
select dr.Field<int>("Age");