Методы построителя запросов (платформа Entity Framework)

Класс ObjectQuery поддерживает как запросы LINQ to Entities, так и Entity SQL для модели Entity Data Model (модель EDM). Класс ObjectQuery также реализует набор методов построителя запросов, которые можно использовать для последовательного конструирования команд запросов, эквивалентных Entity SQL. Ниже приведены методы построителя запросов ObjectQuery наряду с эквивалентными инструкциями Entity SQL:

Метод ObjectQuery Инструкция Entity SQL

Distinct

DISTINCT

Except

EXCEPT

GroupBy

GROUP BY

Intersect

INTERSECT

OfType

OFTYPE

OrderBy

ORDER BY

Select

SELECT

SelectValue

SELECT VALUE

Skip

SKIP

Top

TOP и LIMIT

Union

UNION

UnionAll

UNION ALL

Where

WHERE

Каждый метод построителя запросов возвращает новый экземпляр ObjectQuery. Это позволяет построить запрос, результирующий набор которого основан на операциях последовательности предыдущих экземпляров ObjectQuery. В следующем примере показано применение метода Where для фильтрации возвращенных объектов Product по значению ProductID.

' Return Product objects with the specified ID.
Dim query As ObjectQuery(Of Product) = _
advWorksContext.Product _
.Where("it.ProductID = @product", _
New ObjectParameter("product", productId))
// Return Product objects with the specified ID.
ObjectQuery<Product> query =
    advWorksContext.Product
    .Where("it.ProductID = @product", 
    new ObjectParameter("product", productId));

Поскольку экземпляр ObjectQuery реализует методы IQueryable и IEnumerable, можно объединить методы построителя запросов, реализованные в ObjectQuery, со стандартными методами оператора запроса LINQ, такими как First и Count. В отличие от методов построителя запросов операторы LINQ не возвращают экземпляр ObjectQuery. Дополнительные сведения см. в разделе Общие сведения о стандартных операторах запросов в документации по Visual Studio 2008.

Выбор данных

По умолчанию ObjectQuery возвращает нуль или больше объектов сущности конкретного типа. Вызов последующих методов запросов, таких как Where и OrderBy, влияет на коллекцию объектов, возвращаемых первоначальным методом ObjectQuery. Некоторые методы, такие как Select и GroupBy, возвращают вместо типа сущности проекцию данных, такую как DbDataRecord. Дополнительные сведения см. в разделе Запросы объектов (платформа Entity Framework). В следующем примере возвращается коллекция объектов DbDataRecord, содержащая вложенные типы сущностей SalesOrderHeader.

' Define a query that returns a nested 
' DbDataRecord for the projection.
Dim query As ObjectQuery(Of DbDataRecord) = _
    advWorksContext.Contact.Select("it.FirstName, " _
        + "it.LastName, it.SalesOrderHeader") _
    .Where("it.LastName = 'Zhou'")
// Define a query that returns a nested 
// DbDataRecord for the projection.
ObjectQuery<DbDataRecord> query =
    advWorksContext.Contact.Select("it.FirstName, "
        + "it.LastName, it.SalesOrderHeader")
    .Where("it.LastName = 'Zhou'");

Хотя методы построителя запросов применяются последовательно, можно построить такой же тип вложенных подзапросов, поддерживаемых языком Entity SQL. Для этого необходимо включить подзапрос в метод как код Entity SQL. В следующем примере подзапрос Entity SQL SELECT используется в методе Select, чтобы включить записи LastName, вложенные в результирующий набор и отсортированные в алфавитном порядке по первой букве фамилии:

' Define the query with a GROUP BY clause that returns
' a set of nested LastName records grouped by first letter.
Dim query As ObjectQuery(Of DbDataRecord) = _
advWorksContext.Contact _
.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln") _
.Select("it.ln AS ln, (SELECT c1.LastName " + _
"FROM AdventureWorksEntities.Contact AS c1 " + _
"WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT") _
.OrderBy("it.ln")
// Define the query with a GROUP BY clause that returns
// a set of nested LastName records grouped by first letter.
ObjectQuery<DbDataRecord> query =
    advWorksContext.Contact
    .GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln")    
    .Select("it.ln AS ln, (SELECT c1.LastName " +
    "FROM AdventureWorksEntities.Contact AS c1 " +
    "WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT")
    .OrderBy("it.ln");
NoteПримечание.

При помощи метода ToTraceString просмотрите команду источника данных, которая будет создана объектом ObjectQuery. Дополнительные сведения см. в разделе Запросы объектов (платформа Entity Framework).

Псевдонимы

Методы построителя запросов применяются последовательно, чтобы построить совокупную команду запроса. Это означает, что текущая команда ObjectQuery рассматривается как подзапрос, к которому применяется текущий метод.

NoteПримечание.

Свойство CommandText возвращает команду для экземпляра ObjectQuery.

В методе построителя запросов для ссылки на текущую команду ObjectQuery используется псевдоним. По умолчанию строка «it» является псевдонимом, которая представляет текущую команду, как в следующем примере:

' Return Product objects with a standard cost
' above $10.
Dim productQuery As ObjectQuery(Of Product) = _
advWorksContext.Product _
    .Where("it.StandardCost > 10")
// Return Product objects with a standard cost
// above $10.
ObjectQuery<Product> productQuery =
    advWorksContext.Product
    .Where("it.StandardCost > 10");

Если свойству Name присваивается значение ObjectQuery, это значение становится псевдонимом в последующих методах. Предыдущий пример расширен в следующем примере путем задания для имени ObjectQuery значения «product» и последующим использованием этого псевдонима в последующем методе OrderBy.

' Return Product objects with a standard cost
' above $10.
Dim productQuery As ObjectQuery(Of Product) = _
advWorksContext.Product _
    .Where("it.StandardCost > 10")

'Set the Name property for the query and then 
' use that name as the alias in the subsequent 
' OrderBy method.
productQuery.Name = "product"
Dim filteredProduct As ObjectQuery(Of Product) = _
productQuery.OrderBy("product.ProductID")
// Return Product objects with a standard cost
// above $10.
ObjectQuery<Product> productQuery =
    advWorksContext.Product
    .Where("it.StandardCost > 10");

// Set the Name property for the query and then 
// use that name as the alias in the subsequent 
// OrderBy method.
productQuery.Name = "product";
ObjectQuery<Product> filteredProduct = productQuery
    .OrderBy("product.ProductID");

Параметры

Все методы построителя запросов, которые принимают входную строку Entity SQL, также поддерживают параметризованные запросы. Имена параметров в Entity SQL определены в выражениях запросов с символом (@) в качестве префикса. Дополнительные сведения см. в разделе Параметры (язык Entity SQL). Параметры передаются в методы построителя запросов как массив экземпляров ObjectParameter. В следующем примере два параметра передаются в метод Where:

' Get the contacts with the specified name.
Dim contactQuery As ObjectQuery(Of Contact) = _
    context.Contact _
    .Where("it.LastName = @ln AND it.FirstName = @fn", _
    New ObjectParameter("ln", lastName), _
    New ObjectParameter("fn", firstName))
// Get the contacts with the specified name.
ObjectQuery<Contact> contactQuery = context.Contact
    .Where("it.LastName = @ln AND it.FirstName = @fn",
    new ObjectParameter("ln", lastName), 
    new ObjectParameter("fn", firstName));

Замечания по использованию параметров

При использовании параметров с методами построителя запросов следует учитывать следующие замечания.

  • Параметры, переданные в методы построителя запросов, собираются последующими экземплярами ObjectQuery в последовательности. К ним можно обратиться с помощью свойства Parameters. После добавления параметров их можно удалить из коллекции и очистить коллекцию до момента компиляции или выполнения запроса. Имена параметров изменить нельзя, но значения можно изменить в любое время.

  • Параметры в коллекции ObjectParameterCollection должны быть уникальными. Коллекция не может содержать два параметра с одинаковыми именами.

  • При использовании композиционных методов, таких как Union, UnionAll, Intersect и Except, коллекции параметров объединяются. Исключение возникает в случае несовместимых, неполных наборов параметров или если в коллекциях параметров обоих запросов существуют одинаковые имена.

См. также

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

Запросы к данным как к объектам (платформа Entity Framework)
Формирование результатов запроса (Entity Framework)

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

Запросы к модели EDM (задачи Entity Framework)