単一テーブルのクエリ (LINQ to DataSet)

LINQ (統合言語クエリ) のクエリは、IEnumerable<T> インターフェイスまたは IQueryable<T> インターフェイスが実装されているデータ ソースに対して動作します。 DataTable クラスには、いずれのインターフェイスも実装されていません。そのため、LINQ クエリの From 句でソースとして DataTable を使用する場合は、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

ローカル変数 query はクエリ式で初期化されます。クエリ式は、少なくとも 1 つのクエリ演算子 (標準クエリ演算子、LINQ to DataSet の場合は DataSet クラスに固有の演算子) が適用されることによって、1 つまたは複数の情報ソースに対して機能します。 前の例のクエリ式には、2 つの標準クエリ演算子、WhereSelect が使用されています。

この場合、Where 句では、OnlineOrderFlag = true という条件に基づいてデータを抽出します。 Select 演算子は、その演算子に渡された引数をキャプチャする列挙可能なオブジェクトを割り当てて返します。 上の例では、SalesOrderIDOrderDateSalesOrderNumber の 3 つのプロパティを使って匿名型を作成しています。 この 3 つのプロパティの値は、SalesOrderID テーブルの OrderDate 列、SalesOrderNumber 列、および SalesOrderHeader 列の値に設定されます。

次に、foreach から返された列挙可能なオブジェクトを Select ループで列挙し、クエリ結果を出力します。 クエリは Enumerable を実装する IEnumerable<T> 型であるため、foreach ループでクエリ変数を反復処理するまでクエリは評価されません。 クエリの評価を遅らせることで、繰り返し評価することのできる値としてクエリを維持し、評価のたびに異なる結果を得ることができます。

Field は、DataRow の列値にアクセスするためのメソッドです。また、前出の例には使用されていませんが、SetField を使用すると、DataRow の列値を設定できます。 Field メソッドも SetField メソッドも null 許容値型を扱うことができるため、null 値を明示的にチェックする必要はありません。 また、どちらのメソッドもジェネリック メソッドです。つまり、戻り値の型をキャストする必要はありません。 DataRow の既存の列アクセサー (o["OrderDate"] など) を使用することもできますが、その場合、返されたオブジェクトを適切な型にキャストする必要があります。 列が null 許容値型である場合、IsNull メソッドを使って、値が null かどうかをチェックする必要があります。 詳細については、「ジェネリック メソッド Field および SetField」を参照してください。

T メソッドおよび Field メソッドのジェネリック パラメーター SetField に指定するデータ型は、基になる値の型と一致している必要があります。一致していない場合、InvalidCastException がスローされます。 指定する列の名前も DataSet 内の列名と一致している必要があります。一致していない場合、ArgumentException がスローされます。 どちらの場合も、例外は、実行時にデータが列挙されて、クエリが実行されたときにスローされます。

関連項目