ジェネリック メソッド Field および SetField (LINQ to DataSet)
LINQ to DataSet では、DataRow クラスの拡張メソッドとして、列値にアクセスするための Field メソッドと SetField メソッドが提供されています。 開発者はこれらのメソッドを使用することで、列値に容易にアクセスできます。特に強化されている点は Null 値の扱いです。 DataSet では DBNull.Value を使用して null 値が表されますが、LINQ では Nullable 型と Nullable<T> 型が使用されます。 DataRow の既存の列アクセサーを使用する場合、返されたオブジェクトを適切な型にキャストする必要があります。 DataRow の特定のフィールドで null が許容されている場合、null 値を明示的にチェックする必要があります。DBNull.Value を取得して、それを暗黙的に別の型にキャストしようとすると、InvalidCastException がスローされます。 次の例では、DataRow.IsNull メソッドを使用して null 値をチェックしなかった場合、インデクサーが DBNull.Value を返し、それを String にキャストしようとすると、例外がスローされます。
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
var query =
from product in products.AsEnumerable()
where !product.IsNull("Color") &&
(string)product["Color"] == "Red"
select new
{
Name = product["Name"],
ProductNumber = product["ProductNumber"],
ListPrice = product["ListPrice"]
};
foreach (var product in query)
{
Console.WriteLine("Name: {0}", product.Name);
Console.WriteLine("Product number: {0}", product.ProductNumber);
Console.WriteLine("List price: ${0}", product.ListPrice);
Console.WriteLine("");
}
' 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 products As DataTable = ds.Tables("Product")
Dim query = _
From product In products.AsEnumerable() _
Where product!Color IsNot DBNull.Value AndAlso product!Color = "Red" _
Select New With _
{ _
.Name = product!Name, _
.ProductNumber = product!ProductNumber, _
.ListPrice = product!ListPrice _
}
For Each product In query
Console.WriteLine("Name: " & product.Name)
Console.WriteLine("Product number: " & product.ProductNumber)
Console.WriteLine("List price: $" & product.ListPrice & vbNewLine)
Next
Field は、DataRow の列値にアクセスするためのメソッドです。SetField は、DataRow の列値を設定するためのメソッドです。 Field メソッドも SetField メソッドも Null 許容値型を扱うことができるため、前出の例のように null 値を明示的にチェックする必要はありません。 また、どちらのメソッドもジェネリック メソッドであるため、戻り値の型をキャストする必要もありません。
次の例では、Field メソッドを使用します。
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable products = ds.Tables["Product"];
var query =
from product in products.AsEnumerable()
where product.Field<string>("Color") == "Red"
select new
{
Name = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
ListPrice = product.Field<Decimal>("ListPrice")
};
foreach (var product in query)
{
Console.WriteLine("Name: {0}", product.Name);
Console.WriteLine("Product number: {0}", product.ProductNumber);
Console.WriteLine("List price: ${0}", product.ListPrice);
Console.WriteLine("");
}
' 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 products As DataTable = ds.Tables("Product")
Dim query = _
From product In products.AsEnumerable() _
Where product.Field(Of String)("Color") = "Red" _
Select New With _
{ _
.Name = product.Field(Of String)("Name"), _
.ProductNumber = product.Field(Of String)("ProductNumber"), _
.ListPrice = product.Field(Of Decimal)("ListPrice") _
}
For Each product In query
Console.WriteLine("Name: " & product.Name)
Console.WriteLine("Product number: " & product.ProductNumber)
Console.WriteLine("List price: $ " & product.ListPrice & vbNewLine)
Next
T
メソッドおよび Field メソッドのジェネリック パラメーター SetField に指定するデータ型は、基になる値の型と一致している必要があります。 それ以外の場合、InvalidCastException 例外がスローされます。 指定する列の名前も DataSet 内の列名と一致している必要があります。一致していない場合、ArgumentException がスローされます。 どちらの場合も、例外は、実行時にデータが列挙されて、クエリが実行されたときにスローされます。
SetField メソッド自体は、型変換を一切実行しません。 ただし、型変換がまったく発生しないということではありません。 SetField メソッドでは、DataRow クラスの ADO.NET の動作が公開されています。 DataRow オブジェクトによって型変換が実行され、変換後の値が DataRow オブジェクトに保存される場合もあります。