单表查询 (LINQ to DataSet)

语言集成查询 (LINQ) 查询可用于实现 IEnumerable<T> 接口或 IQueryable<T> 接口的数据源。 DataTable 类不实现任何一个接口,所以如果要使用 DataTable 作为 LINQ 查询的 From 子句中的源,则必须调用 AsEnumerable 方法。

下面的示例获取 SalesOrderHeader 表中的所有联机订单并将订单 ID、订单日期和订单编号输出到控制台。

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from order in orders.AsEnumerable()
    where order.Field<bool>("OnlineOrderFlag") == true
    select new
    {
        SalesOrderID = order.Field<int>("SalesOrderID"),
        OrderDate = order.Field<DateTime>("OrderDate"),
        SalesOrderNumber = order.Field<string>("SalesOrderNumber")
    };

foreach (var onlineOrder in query)
{
    Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
        onlineOrder.SalesOrderID,
        onlineOrder.OrderDate,
        onlineOrder.SalesOrderNumber);
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
    Select New With { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
     }

For Each onlineOrder In query
    Console.Write("Order ID: " & onlineOrder.SalesOrderID)
    Console.Write(" Order date: " & onlineOrder.OrderDate)
    Console.WriteLine(" Order number: " & onlineOrder.SalesOrderNumber)
Next

局部变量查询使用查询表达式进行初始化,该表达式通过应用标准查询运算符中的一个或多个查询运算符,或者在 LINQ to DataSet 的情况下应用特定于 DataSet 类的一个或多个运算符对一个或多个信息源进行运算。 前面示例中的查询表达式使用两个标准查询运算符:WhereSelect

Where 子句基于条件筛选序列,在本例中,OnlineOrderFlag 设置为 trueSelect 运算符分配并返回一个可枚举对象,该对象可捕获传递给运算符的参数。 在上面的示例中,创建了一个具有三个属性的匿名类型:SalesOrderIDOrderDateSalesOrderNumber。 这三个属性的值设置为 SalesOrderID 表中的 OrderDateSalesOrderNumberSalesOrderHeader 列值。

然后,foreach 循环枚举由 Select 返回的可枚举对象,并生成查询结果。 由于查询是一种可以实现 EnumerableIEnumerable<T> 类型,因此,查询的计算将推迟到使用 foreach 循环来循环访问查询变量之后进行。 推迟查询计算可使查询保持为可进行多次计算的值,每次计算都可能生成不同的结果。

Field 方法提供对 DataRow 列值的访问,而 SetField(前面的示例未演示)设置 DataRow 中的列值。 Field 方法和 SetField 方法都可以处理为 null 的值类型,因此不必显式检查 null 值。 这两种方法也都是泛型方法,这意味着您不必强制转换返回类型。 您可以使用 DataRow 中预先存在的列访问器(例如 o["OrderDate"]),但是这样做要求您将返回对象强制转换为相应的类型。 如果列是可以为 null 的值类型,则必须使用 IsNull 方法检查值是否为 null。 有关详细信息,请参阅泛型字段和 SetField 方法

请注意,T 方法和 Field 方法的泛型参数 SetField 中指定的数据类型必须与基础值的类型相匹配,否则将引发 InvalidCastException。 指定的列名称也必须与 DataSet 中的列名称相匹配,否则将引发 ArgumentException。 在这两种情况下,异常都是在执行查询期间的运行时数据枚举时引发的。

请参阅