Поделиться через


Запросы к одиночным таблицам (LINQ to DataSet)

Обновлен: November 2007

Запросы LINQ (Language-Integrated Query) работают с источниками данных, которые реализуют интерфейс IEnumerable<T> или интерфейс IQueryable. Класс DataTable не реализует ни один из этих интерфейсов, в связи с этим необходимо вызывать метод AsEnumerable, если в качестве источника в предложении From запроса LINQ используется DataTable.

В следующем примере получаются все активные заказы из таблицы SalesOrderHeader и выводится на консоль идентификатор, дата и номер заказа.

' 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 orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
    Select New With { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
     }

For Each onlineOrder In query
    Console.Write("Order ID: " & onlineOrder.SalesOrderID)
    Console.Write(" Order date: " & onlineOrder.OrderDate)
    Console.WriteLine(" Order number: " & onlineOrder.SalesOrderNumber)
Next
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from order in orders.AsEnumerable()
    where order.Field<bool>("OnlineOrderFlag") == true
    select new
    {
        SalesOrderID = order.Field<int>("SalesOrderID"),
        OrderDate = order.Field<DateTime>("OrderDate"),
        SalesOrderNumber = order.Field<string>("SalesOrderNumber")
    };

foreach (var onlineOrder in query)
{
    Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
        onlineOrder.SalesOrderID,
        onlineOrder.OrderDate,
        onlineOrder.SalesOrderNumber);
}

Запрос локальной переменной инициализирован выражением запроса, которое работает с одним или несколькими источниками данных, путем выполнения одного или нескольких стандартных операторов запроса или, как в случае LINQ to DataSet, операторов, специфичных для класса DataSet. Выражение запроса в предыдущем примере использует два стандартных оператора запроса: Where и Select.

Предложение Where фильтрует последовательность на основе состояния. В данном случае переменная OnlineOrderFlag установлена в true. Оператор Select назначает и возвращает перечислимый объект, который перехватывает параметры, передаваемые оператору. В предыдущем примере анонимный тип создан с тремя свойствами: SalesOrderID, OrderDate и SalesOrderNumber. Этим трех свойствам присвоены значения из столбцов SalesOrderID, OrderDate и SalesOrderNumber таблицы SalesOrderHeader.

Затем цикл foreach проходит по перечислимому объекту, возвращенному оператором Select, и выдает результаты запроса. Так как этот запрос имеет тип Enumerable, который реализует интерфейс IEnumerable<T>, результат запроса откладывается до тех пор, пока переменная запроса проходит по циклу foreach. Отложенный результат запроса позволяет запросам храниться в виде значений, которые могут вычисляться несколько раз, каждый раз давая потенциально различные результаты.

Метод Field обеспечивает доступ к значениям столбцов DataRow и SetField (что не показано в предыдущем примере) и устанавливает значения столбцов в DataRow. Оба метода, Field и SetField, работают с типами, допускающими значение NULL, поэтому отдельно проверять их на значения NULL не обязательно. Оба метода являются универсальными методами, что означает, что нет необходимости приводить возвращаемый тип. В DataRow нужно использовать предопределенный метод доступа к столбцам (например, o["OrderDate"]), однако в этом случае приведение возвращаемого объекта к соответствующему типу обязательно. Если столбец допускает значение NULL, необходимо проверить его на значение NULL, используя метод IsNull. Дополнительные сведения см. в разделе Универсальные методы Field и SetField (LINQ to DataSet).

Обратите внимание, что тип данных, определяемый в универсальном параметре T методов Field и SetField, должен соответствовать типу базового значения, иначе сформируется исключение InvalidCastException. Назначенное имя столбца должно соответствовать имени столбца в DataSet, иначе это вызовет исключение ArgumentException. В обоих случаях исключении возникает при перечислении данных во время выполнения в момент выполнения запроса.

См. также

Основные понятия

Перекрестные запросы между таблицами (LINQ to DataSet)

Запрос к типизированным объектам DataSet

Универсальные методы Field и SetField (LINQ to DataSet)