泛型字段和 SetField 方法 (LINQ to DataSet)

LINQ to DataSet 可向 DataRow 类提供用于访问列值的扩展方法:Field 方法和 SetField 方法。 这些方法使开发人员能够更轻松地访问列值,特别是 Null 值。 DataSet 使用 DBNull.Value 表示 NULL 值,而 LINQ 使用 NullableNullable<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 值。 这两种方法也都是泛型方法,因此不必强制转换返回类型。

下面的示例使用 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 对象。

请参阅