Универсальные методы 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: {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.