回顾DataSet和DataTable
使用各种DataSet和DataTable索引器时,可通过一种相当直接却是弱类型的方式来数据交互。例如:
static void PrintDataWithIndexers(DataTable dt)
{
// 输出DataTable
for ( int curRow = 0 ; curRow < dt.Rows.Count; curRow ++ )
{
for ( int curCol = 0 ; curCol < dt.Columns.Count; curCol ++ )
{
Console.Write(dt.Rows[curRow][curCol].ToString + " \t " );
}
Console.WriteLine();
}
}
static void PrintDataWithDataTableReader(DataTable dt)
{
// 获取DataTableReader模型
DataTableReader dtReader = dt.CreateDataReader();
while (dtReader.Read())
{
for ( int i = 0 ; i < dtReader.FieldCount; i ++ )
{
Console.Write( " {0}\t " , dtReader.GetValue(i));
}
Console.WriteLine();
}
dtRader.Close();
}
DataSet扩展的作用
System.Data.DataSetExtensions.dll程序集使用一些新的成员,扩展了System.Data命名空间。其中最有用的两个成员是DataTableExtensions和DataRowExtensions。这些类型使用一组扩展方法扩展了DataTable和DataRow的功能。还有一个关键类型是TypedTableBaseExtensions,它定义了可用于强类型DataSet对象的扩展方法,其内部的DataTable对象支持Linq。
获取Linq兼容的DataTable
如果我们希望把DataTable转换为Linq兼容对象,只需调用DataTableExtensions类型定义的AsEnumerable()扩展方法。它会返回EnumerableRowCollection对象,其中包含了DataRow的集合。使用该类型,我们可以操作每一行。示例代码:
// 假定我们已有一个Car类
class Car
{
public string ID;
public string Name;
public int Speed;
}
// 假定DataTable中存储的是Car类信息
static void PrintCarID(DataTable data)
{
// 获取DataTable的enumerable版本
EnumerableRowCollection enumData = data.AsEnumerable();
// 输出汽车的ID值
foreach (DataRow r in enumData)
Console.WriteLine( " Car ID = {0} " , r[ " ID " ]);
}
EnumerableRowCollection实现了IEnumerable<T>接口,因此我们可以使用以下方法来新建一个投影:
static void ApplyLinqQuery(DataTable data)
{
// 投影一个Speed大于5的新结果集
var cars = from car in data.AsEnumerable()
where (int)car[ " Speed " ] > 5
select new
{
ID = (string)car[ " ID " ],
Name = (string)car[ " Name " ]
};
foreach (var item in cars)
{
Console.WriteLine( " ID = {0}, Name = {1} " , item.ID, item.Name);
}
}
当前的Linq查询表达式中使用了许多强制类型转换运算符和DataRow索引器来收集结果集。为了把强类型注入查询中,可使用DataRow类型的Field<T>()扩展方法,这样,我们可以为查询增加类型安全。上例代码可改为:
static void ApplyLinqQuery(DataTable data)
{
// 投影一个Speed大于5的新结果集
var cars = from car in data.AsEnumerable()
where car.Field<int>( " Speed ") > 5
select new
{
ID = car.Field<string>( " ID ") ,
Name = car.Field<string>( " Name ")
};
foreach (var item in cars)
{
Console.WriteLine( " ID = {0}, Name = {1} " , item.ID, item.Name);
}
}
从Linq查询产生新的DataTable
如果我们有一个结果集,其基础类型可表示为IEnumerable<T>,那么我们就可以结果上调用CopyToDataTable<T>()扩展方法,如:
static void ApplyLinqQuery(DataTable data)
{
// 投影一个Speed大于5的新结果集
var cars = from car in data.AsEnumerable()
where car.Field<int>( " Speed ") > 5
select new
{
ID = car.Field<string>( " ID ") ,
Name = car.Field<string>( " Name ")
};//使用结果集来构建新的DataTableDataTable newTable = cars.CopyToDataTable();........ //输出DataTable
}
如果希望使用Linq查询的结果来作为数据绑定源,该方法就很有用。
我们还可以通过AsDataView<T>()扩展方法把Linq查询转换为DataView类型。