LINQ to DataSet 提供擴充方法至 DataRow 類別,以存取欄位值:Field 方法和 SetField 方法。 這些方法可讓開發人員更輕鬆地存取列值,特別是在處理空值的情況下。 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: {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方法都會處理可為 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: {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 會公開 DataRow 類別的 ADO.NET 行為。 型別轉換可由 DataRow 物件執行,然後轉換後的值會儲存至 DataRow 物件。