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


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

Класс ObjectQuery поддерживает запросы LINQ to Entities и Entity SQL к концептуальной модели. Класс 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) = context.Products.Where("it.ProductID = @product", New ObjectParameter("product", productId))
// Return Product objects with the specified ID.
ObjectQuery<Product> query =
    context.Products
    .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) = context.Contacts.Select("it.FirstName, it.LastName, it.SalesOrderHeaders") _
                                            .Where("it.LastName = @ln", New ObjectParameter("ln", lastName))
// Define a query that returns a nested 
// DbDataRecord for the projection.
ObjectQuery<DbDataRecord> query =
    context.Contacts.Select("it.FirstName, "
        + "it.LastName, it.SalesOrderHeaders")
    .Where("it.LastName = @ln", new ObjectParameter("ln", lastName));

Хотя методы построителя запросов применяются последовательно, можно построить такой же тип вложенных запросов, который поддерживается языком 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) = _
    context.Contacts.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln") _
    .Select("it.ln AS ln, (SELECT c1.LastName FROM AdventureWorksEntities.Contacts 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 =
    context.Contacts
    .GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln")
    .Select("it.ln AS ln, (SELECT c1.LastName " +
    "FROM AdventureWorksEntities.Contacts AS c1 " +
    "WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT")
    .OrderBy("it.ln");
Bb896238.note(ru-ru,VS.100).gifПримечание
Используйте метод ToTraceString, чтобы увидеть команду источника данных, которая будет сформирована методом ObjectQuery.Дополнительные сведения см. в разделе Запросы объектов (платформа Entity Framework).

Псевдонимы

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

Bb896238.note(ru-ru,VS.100).gifПримечание
Свойство CommandText возвращает команду для экземпляра ObjectQuery.

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

' Return Product objects with a standard cost 
' above 10 dollars. 
Dim cost = 10
Dim productQuery As ObjectQuery(Of Product) = context.Products.Where("it.StandardCost > @cost")
productQuery.Parameters.Add(New ObjectParameter("cost", cost))
int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
    context.Products
    .Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));

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

' Return Product objects with a standard cost 
' above 10 dollars. 
Dim cost = 10
Dim productQuery As ObjectQuery(Of Product) = context.Products.Where("it.StandardCost > @cost")
productQuery.Parameters.Add(New ObjectParameter("cost", cost))

' 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")
int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
    context.Products
    .Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));

// 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.Contacts.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.Contacts
    .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)