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


Знакомство с LINQ в Visual Basic

Обновлен: Ноябрь 2007

Встроенные в язык запросы (LINQ) добавляют возможности запросов в Visual Basic и обеспечивают простые и мощные возможности обработки всех видов данных. В отличие от отправки запроса для его обработки в базе данных или работы с разным синтаксисом запросов для каждого типа искомых данных, LINQ ввводит запросы как часть языка Visual Basic. В нем независимо от типа данных используется унифицированный синтаксис.

LINQ позволяет запрашивать данные из базы данных SQL Server, XML, массивов и коллекций в памяти, наборов данных ADO.NET или любого другого локального или удаленного источника данных, который поддерживает LINQ. Все это можно делать с помощью обычных элементов языка Visual Basic. Поскольку запросы пишутся на языке Visual Basic, результаты запроса возвращаются в виде строго типизированных объектов. Эти объекты поддерживают технологию IntelliSense, что позволяет писать код быстрее и перехватывать ошибки в запросах при компиляции, а не при выполнении. Запросы LINQ можно использовать в качестве источника дополнительных запросов для уточнения результатов. Они также могут быть связаны с элементами управления, чтобы пользователи легко могли просматривать и изменять результаты запроса.

Например, в следующем примере кода показан запрос LINQ, возвращающий список заказчиков из коллекции, и группирующий их по расположению.

Dim customers As List(Of Customer) = GetCustomerList()

Dim customersByCountry = From cust In customers _
                         Order By cust.Country, cust.City _
                         Group By CountryName = cust.Country _
                         Into RegionalCustomers = Group, Count() _
                         Order By CountryName

For Each country In customersByCountry
  Console.WriteLine(country.CountryName & _
                    " (" & country.Count & ")" & vbCrLf)

  For Each customer In country.RegionalCustomers
    Console.WriteLine(vbTab & customer.CompanyName & _
                      " (" & customer.City & ")")
  Next
Next

В этом разделе содержатся сведения о следующих областях:

  • Поставщики LINQ

  • Структура запроса LINQ

  • Операторы запросов LINQ в Visual Basic

  • Подключение к базе данных с помощью LINQ to SQL

  • Возможности Visual Basic, поддерживающего LINQ

  • Отложенное и немедленное выполнение запроса

  • XML в Visual Basic

  • Связанные ресурсы

  • Практические и пошаговые руководства

Поставщики LINQ

Поставщик LINQ сопоставляет запросы LINQ Visual Basic с запрашиваемым источником данных. При написании запроса LINQ поставщик принимает запрос и переводит его в команды, которые источник данных будет способен выполнить. Поставщик также преобразует данные из источника в объекты, составляющие результат запроса. Наконец, он преобразует объекты в данные при отправке обновлений на источник данных.

Visual Basic содержит следующие поставщики LINQ.

  • LINQ to Objects
    Поставщик LINQ to Objects позволяет делать запросы к коллекциям и массивам, находящимся в памяти. Если объект поддерживает интерфейс IEnumerable или IEnumerable<T>, поставщик LINQ to Objects позволяет делать к объекту запросы.

    Можно включить поставщик LINQ to Objects путем импорта пространства имен System.Linq, которое импортируется по умолчанию для всех проектов Visual Basic.

    Дополнительные сведения о поставщике LINQ to Objects см. в разделе LINQ to Objects.

  • LINQ to SQL
    Поставщик LINQ to SQL позволяет запрашивать и изменять данные в базе данных SQL Server. Это упрощает сопоставление объектной модели приложения и таблиц и объектов в базе данных.

    Visual Basic упрощает работу с LINQ to SQL включением реляционного конструктора объектов (O/R-конструктора). Этот конструктор используется для создания объектной модели приложения, сопоставляемой с объектами в базе данных. O/R конструктор также предоставляет функциональные возможности для сопоставления хранимых процедур и функций с объектом DataContext, который управляет связью с базами данных и сохраняет состояние проверок оптимистической блокировки.

    Дополнительные сведения о поставщике LINQ to SQL см. в разделе LINQ to SQL. Дополнительные сведения о реляционном конструкторе объектов см. в разделе Реляционный конструктор объектов.

  • LINQ to XML
    Поставщик LINQ to XML позволяет запрашивать и изменять XML. Можно изменить XML в памяти, загрузить его из файла, сохранить в файл.

    Кроме того, поставщик LINQ to XML разрешает использование литералов XML и свойств оси XML, что позволяет писать XML непосредственно в коде Visual Basic. Дополнительные сведения см. в разделе XML в Visual Basic.

  • LINQ to DataSet
    Поставщик LINQ to DataSet позволяет запрашивать и обновлять данные в наборе данных ADO.NET. Можно добавить мощь LINQ в использующие наборы данных приложения, чтобы упростить и расширить возможности составления запросов к набору данных, его статистической обработки и обновления данных.

    Дополнительные сведения см. в разделе LINQ to DataSet.

Структура запроса LINQ

Запрос LINQ, часто называемый как выражение запроса, состоит из комбинации предложений запросов, определяющих источники данных и переменные итерации для запроса. Выражение запроса может также включать инструкции сортировки, фильтрации, группировки и соединения, а также вычисления, применимые к источнику данных. Синтаксис выражения запроса напоминает синтаксис SQL; поэтому большая часть синтаксиса может показаться знакомой.

Выражение запроса начинается с предложения From. Это предложение указывает исходные данные для запроса и переменные, которые используются для обращения к каждому элементу источника данных по отдельности. Эти переменные называются переменные диапазона или итерационные переменные. Предложение From является обязательным для запроса, за исключением запросов Aggregate, в которых предложение From необязательно. После определения области и источника запроса в предложении From или Aggregate можно использовать любую комбинацию предложений запроса для его уточнения. Подробные сведения о предложениях запросов можно найти в теме "Операторы Visual Basic запросов LINQ" далее в этом разделе. Например, следующий запрос определяет исходную коллекцию данных клиента как переменную customers и как итерационная переменная cust.

Dim queryResults = From cust In customers _
                   Select cust.CompanyName

Данный пример сам по себе является допустимым запросом; однако запрос становится гораздо более мощным при добавлении нескольких предложений для уточнения результата. Например, можно добавить предложение Where для фильтрации результата по одному или нескольким значениям. Выражения запроса — это одна строка кода; можно просто добавлять дополнительные предложения в конец запроса. Можно разбить запрос на несколько строк текста для улучшения читаемости с помощью знака продолжения строки (_). В следующем примере кода показан пример запроса с предложением Where.

Dim queryResults = From cust In customers _
                   Where cust.Country = "USA"

Другое мощное предложение запроса — предложение Select. Оно позволяет возвращать только выбранные поля из источника данных. Запросы LINQ возвращают перечислимые коллекции строго типизированных объектов. Запрос может вернуть коллекцию как анонимных, так и именованных типов. Можно использовать предложение Select для получения только одного поля из источника данных. При этом тип возвращаемой коллекции — это тип этого поля. Можно также использовать предложение Select для получения нескольких полей из источника данных. При этом тип возвращаемой коллекции — это новый анонимный тип. Можно также сопоставить возвращенные запросом поля с полями указанного именованного типа. В следующем примере кода показано выражение запроса, возвращающее коллекцию анонимных типов, члены которых заполняются данными из выбранных полей источника данных.

Dim queryResults = From cust In customers _
               Where cust.Country = "USA" _
               Select cust.CompanyName, cust.Country

Запросы LINQ могут также использоваться для объединения нескольких источников данных и получения единого результата. Это можно сделать с помощью одного или нескольких предложений From или с помощью предложений Join или Group Join. В следующем примере кода показано выражение запроса, объединяющее данные клиентов и заказов и возвращающее коллекцию анонимных типов, содержащих их данные.

Dim queryResults = From cust In customers, ord In orders _
                   Where cust.CustomerID = ord.CustomerID _
                   Select cust, ord

Можно использовать предложение Group Join для получения иерархического результата запроса, содержащего коллекцию объектов клиента. Каждый объект клиента имеет свойство, содержащее коллекцию всех заказов этого клиента. В следующем примере показано выражение запроса, объединяющее данные клиентов и заказов как иерархический результат и возвращающее коллекцию анонимных типов. Запрос возвращает тип, у которого есть свойство CustomerOrders, содержащее коллекцию данных заказов клиента. У него также есть свойство OrderTotal, которое содержит общую сумму всех заказов этого клиента. (Этот запрос эквивалентен LEFT OUTER JOIN.)

Dim queryResults = From cust In customers _
                   Group Join ord In orders On _
                     cust.CustomerID Equals ord.CustomerID _
                     Into CustomerOrders = Group, _
                          OrderTotal = Sum(ord.Total) _
                   Select cust.CompanyName, cust.CustomerID, _
                          CustomerOrders, OrderTotal

Имеется несколько дополнительных операторов запросов LINQ, которые можно использовать для создания мощных выражений запросов. В следующей теме этого раздела описываются различные предложения запросов, которые можно использовать в выражениях запросов. Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).

Операторы запросов LINQ в Visual Basic

Классы в поддерживающих запросы LINQ пространствах имен (в частности, System.Linq) содержат методы создания и уточнения запросов. Их можно использовать исходя из нужд приложения. Visual Basic содержит ключевые слова для наиболее общих предложений запросов, как описано в следующей таблице.

  • Условие From (Visual Basic)
    Предложение From или Aggregate требуется для начала запроса. Предложение From определяет коллекцию источника и переменную итерации для запроса. Пример.

    ' Returns the company name for all customers for whom
    ' State is equal to "WA".
    Dim names = From cust In customers _
                Where cust.State = "WA" _
                Select cust.CompanyName
    
  • Предложение Select (Visual Basic)
    Необязательное. Объявляет набор переменных итераций для запроса. Пример.

    ' Returns the company name and ID value for each
    ' customer as a collection of a new anonymous type.
    Dim customerList = From cust In customers _
                       Select cust.CompanyName, cust.CustomerID
    

    Если не указано предложение Select, то переменные итераций для запроса — это переменные итераций, указанные в предложении From или Aggregate.

  • Предложение Where (Visual Basic)
    Необязательное. Устанавливает условия фильтрации для запроса. Пример.

    ' Returns all product names for which the Category of
    ' the product is "Beverages".
    Dim names = From product In products _
                Where product.Category = "Beverages" _
                Select product.Name
    
  • Предложение Order By (Visual Basic)
    Необязательное. Устанавливает порядок сортировки для столбцов в запросе. Пример.

    ' Returns a list of books sorted by price in 
    ' ascending order.
    Dim titlesAscendingPrice = From b In books _
                               Order By b.price
    
  • Предложение Join (Visual Basic)
    Необязательное. Объединяет две коллекции в одну. Пример.

    ' Returns a combined collection of all of the 
    ' processes currently running and a descriptive
    ' name for the process taken from a list of 
    ' descriptive names.
    Dim processes = From proc In Process.GetProcesses _
                    Join desc In processDescriptions _
                      On proc.ProcessName Equals desc.ProcessName _
                    Select proc.ProcessName, proc.Id, desc.Description
    
  • Предложение Group By (Visual Basic)
    Необязательное. Группирует элементы результата запроса. Может использоваться для применения статистических функций к каждой группе. Пример.

    ' Returns a list of orders grouped by the order date
    ' and sorted in ascending order by the order date.
    Dim orderList = From order In orders _
                    Order By order.OrderDate _
                    Group By OrderDate = order.OrderDate _
                    Into OrdersByDate = Group
    
  • Предложение Group Join (Visual Basic)
    Необязательное. Объединяет две коллекции в одну иерархическую. Пример.

    ' Returns a combined collection of customers and
    ' customer orders.
    Dim customerList = From cust In customers _
                       Group Join ord In orders On _
                         cust.CustomerID Equals ord.CustomerID _
                       Into CustomerOrders = Group, _
                            TotalOfOrders = Sum(ord.Total) _
                       Select cust.CompanyName, cust.CustomerID, _
                              CustomerOrders, TotalOfOrders
    
  • Статистическое предложение (Visual Basic)
    Предложение From или Aggregate требуется для начала запроса. Предложение Aggregate применяет одну или несколько статистических функций к коллекции. Например, можно использовать предложение Aggregate для вычисления суммы всех возвращенных запросом элементов.

    ' Returns the sum of all order totals.
    Dim orderTotal = Aggregate order In orders _
                     Into Sum(order.Total)
    

    Предложение Aggregate можно также использовать для изменения запроса. Например, можно использовать предложение Aggregate для выполнения вычислений с результатом связанного запроса.

    ' Returns the customer company name and largest 
    ' order total for each customer.
    Dim customerMax = From cust In customers _
                      Aggregate order In cust.Orders _
                      Into MaxOrder = Max(order.Total) _
                      Select cust.CompanyName, MaxOrder
    
  • Предложение Let (Visual Basic)
    Необязательное. Вычисляет значение и присваивает его новой переменной в запросе. Пример.

    ' Returns a list of products with a calculation of
    ' a ten percent discount.
    Dim discountedProducts = From prod In products _
                             Let Discount = prod.UnitPrice * 0.1 _
                             Where Discount >= 50 _
                             Select prod.Name, prod.UnitPrice, Discount
    
  • Предложение Distinct (Visual Basic)
    Необязательное. Ограничивает значения текущей переменной итерации, чтобы исключить повторяющиеся значения в результатах запроса. Пример.

    ' Returns a list of cities with no duplicate entries.
    Dim cities = From item In customers _
                 Select item.City _
                 Distinct
    
  • Предложение Skip (Visual Basic)
    Необязательное. Пропускает заданное число элементов в коллекции и возвращает остальные элементы. Пример.

    ' Returns a list of customers. The first 10 customers
    ' are ignored and the remaining customers are
    ' returned.
    Dim customerList = From cust In customers _
                       Skip 10
    
  • Предложение Skip While (Visual Basic)
    Необязательное. Пропускает элементы в коллекции, пока заданное условие является true и затем возвращает оставшиеся элементы. Пример.

    ' Returns a list of customers. The query ignores all
    ' customers until the first customer for whom
    ' IsSubscriber returns false. That customer and all
    ' remaining customers are returned.
    Dim customerList = From cust In customers _
                       Skip While IsSubscriber(cust)
    
  • Предложение Take (Visual Basic)
    Необязательное. Возвращает указанное число последовательных элементов от начала коллекции. Пример.

    ' Returns the first 10 customers.
    Dim customerList = From cust In customers _
                       Take 10
    
  • Предложение Take While (Visual Basic)
    Необязательное. Включает элементы в коллекцию, пока заданное условие является true, и затем пропускает оставшиеся элементы. Пример.

    ' Returns a list of customers. The query returns
    ' customers until the first customer for whom 
    ' HasOrders returns false. That customer and all 
    ' remaining customers are ignored.
    Dim customersWithOrders = From cust In customers _
                              Order By cust.Orders.Count Descending _
                              Take While HasOrders(cust)
    

Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).

Можно использовать дополнительные возможности запросов LINQ путем обращения к членам перечислимых и доступных для запроса типов, предоставляемых LINQ. Можно использовать эти дополнительные возможности, вызвав конкретный оператор запроса на результате выражения запроса. Например, код следующего примера использует метод Union для объединения результатов двух запросов в один. Он использует метод ToList<TSource> для возвращения результата запроса в виде универсального списка.

VbVbalrIntroToLINQ#22

Сведения о дополнительных возможностях LINQ см. в Общие сведения о стандартных операторах запроса.

Подключение к базе данных с помощью LINQ to SQL

В Visual Basic идентификация объектов базы данных SQL Server (таблицы, представления, хранимые процедуры), к которым нужен доступ, происходит с помощью файла LINQ to SQL. Файл LINQ to SQL имеет расширение .dbml.

При наличии допустимого подключения к базе данных SQL Server можно добавить в проект шаблон элемента Классы LINQ to SQL. Это даст возможность отобразить реляционный конструктор объектов (O/R-конструктор). O/R-конструктор дает возможность перетаскивать элементы, к которым нужен доступ в коде, из Обозревателя серверов / Обозревателя баз данных на поверхность конструктора. Файл LINQ to SQL добавляет объект DataContext в проект. Этот объект включает в себя свойства и коллекции для таблиц и представлений, к которым нужен доступ, а также необходимые методы для хранимых процедур. После сохранения изменений в файле LINQ to SQL (.dbml) можно получить доступ к этим объектам в коде, обратившись к определенному O/R-конструктором объекту DataContext. Объекту DataContext для проекта присваивается имя на основе имени файла LINQ to SQL. Например, файл LINQ to SQL с именем Northwind.dbml создаст объект DataContext с именем NorthwindDataContext.

Примеры с пошаговыми инструкциями см. в разделах Практическое руководство. Выполнение запросов к базе данных с помощью LINQ (Visual Basic) и Практическое руководство. Вызов хранимой процедуры с помощью LINQ (Visual Basic).

Возможности Visual Basic, поддерживающего LINQ

Visual Basic имеет другие важные возможности, упрощающие использование LINQ и уменьшающие требуемый для написания запросов объем кода. Ниже перечислены некоторые из этих методов.

  • Анонимные типы, позволяющие создать новый тип, основанный на результатах запроса.

  • Неявно типизированные переменные, позволяющие отложить указание типа и позволить компилятору передавать тип, основанный на результатах запроса.

  • Методы расширения, позволяющие расширять существующий тип своими собственными методами без изменения самого типа.

Дополнительные сведения см. в разделе Возможности Visual Basic, поддерживающие LINQ.

Отложенное и немедленное выполнение запроса

Выполнение запроса разделено с его созданием. После создания запроса его выполнение инициируется отдельным механизмом. Запрос может выполняться по мере его определения (немедленное выполнение), или его определение может быть сохранено и запрос может быть выполнен позднее (отложенное выполнение).

По умолчанию при создании запроса он не выполняется. Вместо этого определение запроса хранится в переменной, используемой для ссылки на результаты запроса. Если доступ к переменной результата запроса выполняется позже в коде, например в цикле For…Next, запрос выполняется. Такой процесс называется отложенным выполнением.

Запросы могут также выполняться при их определении. Это называется немедленное выполнение. Можно инициировать немедленное выполнение, применив метод, требующий доступа к отдельным элементам результата запроса. Это может быть результатом использования статистических функций, таких как Count, Sum, Average, Min или Max. Дополнительные сведения о статистических функциях см. в разделе Статистическое предложение (Visual Basic).

Использование методов ToList или ToArray также приведет к немедленному выполнению. Это может быть полезно, если надо выполнить запрос немедленно и занести результаты в кэш. Дополнительные сведения об этих методах см. в разделе Преобразование типов данных.

Дополнительные сведения о выполнении запроса см. в разделе Написание первого запроса LINQ (Visual Basic).

XML в Visual Basic

Возможности XML в Visual Basic включают литералы XML и свойства оси XML, что позволяет легко создавать, запрашивать, изменять и получать доступ к XML в коде. Литералы XML позволяют писать XML непосредственно в коде. Компилятор Visual Basic обрабатывает XML как объект данных первого класса.

В следующем примере показано, как создать элемент XML, получить доступ к его дочерним элементам и атрибутам и делать запросы к содержимому элемента с помощью LINQ.

' Place Imports statements at the top of your program.  
Imports <xmlns:ns="http://SomeNamespace">

Module Sample1

    Sub SampleTransform()

        ' Create test by using a global XML namespace prefix. 

        Dim contact = _
            <ns:contact>
                <ns:name>Patrick Hines</ns:name>
                <ns:phone ns:type="home">206-555-0144</ns:phone>
                <ns:phone ns:type="work">425-555-0145</ns:phone>
            </ns:contact>

        Dim phoneTypes = _
          <phoneTypes>
              <%= From phone In contact.<ns:phone> _
                  Select <type><%= phone.@ns:type %></type> _
              %>
          </phoneTypes>

        Console.WriteLine(phoneTypes)
    End Sub

End Module

Дополнительные сведения см. в разделе XML в Visual Basic.

Связанные ресурсы

  • XML в Visual Basic
    Описание возможностей XML в Visual Basic, к которым можно делать запросы и которые позволяют включать XML как объекты данных первого класса в коде Visual Basic.

  • Запросы (Visual Basic)
    Содержит справочные сведения о предложениях запросов, которые доступны в Visual Basic.

  • LINQ
    Содержит общие сведения, рекомендации по программированию и примеры для LINQ.

  • LINQ to SQL
    Содержит общие сведения, рекомендации по программированию и примеры для LINQ to SQL.

  • LINQ to Objects
    Содержит общие сведения, рекомендации по программированию и примеры для LINQ to Objects.

  • LINQ to ADO.NET (Страница портала)
    Содержит ссылки на общие сведения, рекомендации по программированию и примеры для LINQ ADO.NET.

  • LINQ to XML
    Содержит общие сведения, рекомендации по программированию и примеры для LINQ to XML.

Практические и пошаговые руководства

Практическое руководство. Выполнение запросов к базе данных с помощью LINQ (Visual Basic)

Практическое руководство. Вызов хранимой процедуры с помощью LINQ (Visual Basic)

Практическое руководство. Изменение данных в базе данных с помощью LINQ (Visual Basic)

Практическое руководство. Объединение данных с помощью LINQ с использованием объединений (Visual Basic)

Практическое руководство. Сортировка коллекции с помощью LINQ (Visual Basic)

Практическое руководство. Фильтрование результатов запроса с помощью LINQ (Visual Basic)

Практическое руководство. Выполнение над данными функций Count, Sum и Average с помощью LINQ (Visual Basic)

Практическое руководство. Поиск минимального или максимального значения в результатах запроса с помощью LINQ (Visual Basic)

Пошаговое руководство. Создание классов LINQ to SQL (реляционный конструктор объектов)

Как назначить хранимые процедуры для выполнения обновлений, вставок и удалений (реляционный конструктор объектов)

См. также

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

Общие сведения о LINQ to XML в Visual Basic

Общие сведения о LINQ to DataSet

Методы DataContext (реляционный конструктор объектов)

Другие ресурсы

LINQ

LINQ to SQL

Примеры LINQ

Реляционный конструктор объектов