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

LINQ to DataSet 为用于访问列值的类提供扩展方法 DataRowField 方法和 SetField 方法。 这些方法为开发人员提供了访问列值的更便捷方式,特别是在处理 null 值时。 DataSet 使用 DBNull.Value 来表示 null 值,而 LINQ 使用 NullableNullable<T> 类型。 使用 DataRow 中预先存在的列访问器需要将返回对象强制转换成相应的类型。 如果某个 DataRow 特定字段可能为 null,则必须显式检查该 null 值,因为返回 DBNull.Value 并将其隐式转换为其他类型时会抛出一个 InvalidCastException。 在下面的示例中,如果 DataRow.IsNull 方法未用于检查 null 值,则如果索引器返回 DBNull.Value 并尝试将其强制转换为 a 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 的列值的访问,SetFieldDataRow 中设置列值。 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

请注意,方法的Field泛型参数T中指定的数据类型必须与SetField基础值的类型匹配。 否则,将引发 InvalidCastException 异常。 指定的列名称也必须与 DataSet 中的列名称相匹配,否则将引发 ArgumentException。 在这两种情况下,异常都是在执行查询期间的运行时数据枚举时引发的。

该方法 SetField 本身不执行任何类型转换。 但这并不意味着不会发生类型转换。 该SetField方法公开了DataRow类的ADO.NET行为。 类型转换可由对象执行 DataRow ,然后转换后的值将保存到 DataRow 该对象。

另请参阅