LINQ to DataSet은 DataRow 클래스에 열 값에 액세스하기 위한 확장 메서드인 Field 메서드와 SetField 메서드를 제공합니다. 이러한 메서드는 특히 null 값과 관련하여 개발자에게 열 값에 더 쉽게 액세스할 수 있도록 합니다. DataSet는 null 값을 나타내기 위해 DBNull.Value를 사용하고, 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: {product.Name}");
Console.WriteLine($"Product number: {product.ProductNumber}");
Console.WriteLine($"List price: ${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 메서드는 모두 nullable 값 형식을 처리하므로 이전 예제와 같이 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: {product.Name}");
Console.WriteLine($"Product number: {product.ProductNumber}");
Console.WriteLine($"List price: ${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 클래스의 ADO.NET 동작을 노출합니다 DataRow . 형식 변환은 개체에 의해 DataRow 수행될 수 있으며 변환된 값은 개체에 DataRow 저장됩니다.