単一テーブルのクエリ (LINQ to DataSet)
更新 : November 2007
統合言語クエリ (LINQ: Language-Integrated Query) のクエリは、IEnumerable<T> インターフェイスまたは IQueryable インターフェイスを実装するデータ ソースに対して動作します。DataTable クラスには、いずれのインターフェイスも実装されていません。そのため、LINQ クエリの From 句でソースとして DataTable を使用する場合は、AsEnumerable メソッドを呼び出す必要があります。
次の例では、SalesOrderHeader テーブルからオンラインでの注文をすべて取得し、注文 ID、注文日、および注文番号をコンソールに出力します。
' 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
// 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);
}
ローカル変数 query はクエリ式で初期化されます。クエリ式は、少なくとも 1 つのクエリ演算子 (標準クエリ演算子、LINQ to DataSet の場合は DataSet クラスに固有の演算子) が適用されることによって、1 つまたは複数の情報ソースに対して機能します。前の例のクエリ式には、2 つの標準クエリ演算子、Where と Select が使用されています。
この場合、Where 句では、OnlineOrderFlag = true という条件に基づいてデータを抽出します。Select 演算子は、その演算子に渡された引数をキャプチャする列挙可能なオブジェクトを割り当てて返します。上の例では、SalesOrderID、OrderDate、SalesOrderNumber の 3 つのプロパティを使って匿名型を作成しています。この 3 つのプロパティの値は、SalesOrderHeader テーブルの SalesOrderID 列、OrderDate 列、および SalesOrderNumber 列の値に設定されます。
次に、Select から返された列挙可能なオブジェクトを foreach ループで列挙し、クエリ結果を出力します。クエリは IEnumerable<T> を実装する Enumerable 型であるため、foreach ループでクエリ変数を反復処理するまでクエリは評価されません。クエリの評価を遅らせることで、繰り返し評価することのできる値としてクエリを維持し、評価のたびに異なる結果を得ることができます。
Field は、DataRow の列値にアクセスするためのメソッドです。また、前出の例には使用されていませんが、SetField を使用すると、DataRow の列値を設定できます。Field メソッドも SetField メソッドも Null 許容型を扱うことができるため、Null 値を明示的にチェックする必要はありません。また、どちらのメソッドもジェネリック メソッドです。つまり、戻り値の型をキャストする必要はありません。DataRow の既存の列アクセサ (o["OrderDate"] など) を使用することもできますが、その場合、返されたオブジェクトを適切な型にキャストする必要があります。列に NULL 値が許容されている場合、IsNull メソッドを使って、値が NULL かどうかをチェックする必要があります。詳細については、「ジェネリック メソッド Field および SetField (LINQ to DataSet)」を参照してください。
Field メソッドおよび SetField メソッドのジェネリック パラメータ T に指定するデータ型は、基になる値の型と一致している必要があります。一致していない場合、InvalidCastException がスローされます。指定する列の名前も DataSet 内の列名と一致している必要があります。一致していない場合、ArgumentException がスローされます。どちらの場合も、例外は、実行時にデータが列挙されて、クエリが実行されたときにスローされます。