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


Запросы объектов (платформа Entity Framework)

Универсальный класс ObjectQuery представляет запрос, который возвращает коллекцию, включающую от нуля или больше типизированных объектов сущностей. Запрос объектов всегда принадлежит к существующему контексту объекта. В этом контексте содержится информация о соединении и метаданных, необходимая для создания и выполнения запроса. Типизированный класс ObjectContext включает набор свойств, которые возвращают типизированные экземпляры ObjectQuery. Предусмотрено по одному из этих свойств для каждого типа сущности. Эти свойства облегчают создание экземпляра типизированного объекта ObjectQuery. Запрос объектов выполняется в следующих сценариях:

  • Когда над объектом производится операция, например в цикле перечисления foreach (C#) или For Each (Visual Basic).

  • При назначении его для заполнения коллекции List.

  • При явном вызове метода Execute.

  • При вызове оператора выполнения запроса LINQ, такого как First или Any. Дополнительные сведения см. в разделе Методы построителя запросов (платформа Entity Framework).

В следующем запросе происходит возврат объекта Contact, в котором имя и фамилия указаны с помощью переданных параметров:

' 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));

Полные примеры использования контекста объекта для составления и выполнения запросов см. в разделе Как выполнить запрос, возвращающий тип сущности (платформа Entity Framework). Дополнительные сведения о запросах Entity SQL см. в разделе Язык Entity SQL.

Проекция запроса

Безусловно, запросы объектов предназначены для возврата данных Entity Data Model (модель EDM) в качестве объектов сущностей, но запросы объектов поддерживают также проекции, возвращающие данные, которые невозможно легко материализовать в виде типов сущностей. В запросе ObjectQuery используется тип DbDataRecord для проекций, возвращающих типы, отличные от типов сущностей, которыми могут быть либо вложенные результаты, либо анонимные типы. Простые типы, такие как Int32 или String, используются с проекциями, возвращающими значения отдельных свойств.

Метод построителя запросов Select возвращает запрос ObjectQuery, который после вызова на выполнение возвращает коллекцию объектов DbDataRecord. Проекции запросов поддерживаются обоими инструментами — LINQ to Entities и Entity SQL. Примеры проекций запросов см. в следующих разделах:

При создании проекций запросов принимаются во внимание следующие соображения.

  • Запрос ObjectQuery можно инициализировать так, чтобы он представлял единственный скалярный результат, а не коллекцию скалярных результатов. Некоторые методы расширений требуют на входе коллекцию. В этом случае активизируется исключение ArgumentException при вызове одного из этих методов, как в следующем примере.

    ' Define a query projection that returns 
    ' a single scalar value rather than a collection.
    Dim scalarQuery As ObjectQuery(Of Int32) = _
        New ObjectQuery(Of Int32)("100", advWorksContext)
    
    ' Calling an extension method that requires a collection
    ' will result in an exception.
    Dim hasValues As Boolean = scalarQuery.Any()
    
    // Define a query projection that returns 
    // a single scalar value rather than a collection.
    ObjectQuery<Int32> scalarQuery = 
        new ObjectQuery<Int32>("100", advWorksContext);
    
    // Calling an extension method that requires a collection
    // will result in an exception.
    bool hasValues = scalarQuery.Any(); 
    
  • Если запрос ObjectQuery при его проецировании на тип-примитив может вернуть значение null, то следует использовать версию типа, допускающую значения NULL. В следующем запросе используется версия типа DateTime, допускающая значения NULL, поскольку свойство ShipDate объекта SalesOrderHeader может вернуть значение null.

    Dim shipDateQuery As ObjectQuery(Of Nullable(Of Date)) = _
    advWorksContext.SalesOrderHeader _
        .Where("it.CustomerID = @contactId", _
            New ObjectParameter("contactId", contactId)) _
        .SelectValue(Of Nullable(Of Date))("it.ShipDate")
    
    ObjectQuery<Nullable<DateTime>> shipDateQuery =
        advWorksContext.SalesOrderHeader
        .Where("it.CustomerID = @contactId",
            new ObjectParameter("contactId", contactId))
        .SelectValue<Nullable<DateTime>>("it.ShipDate");
    

    Дополнительные сведения см. в разделе Типы, допускающие значения NULL (Руководство по программированию на Visual Basic) или Типы, допускающие значения NULL (руководство по программированию на C#).

Задание времени ожидания команды

По умолчанию время ожидания для запросов объектов и операции SaveChanges определяется основным поставщиком соединений. Но это заданное по умолчанию время ожидания можно переопределить с помощью свойства CommandTimeout объекта ObjectContext, как показано в следующем примере.

' Specify a timeout for queries in this context, in seconds.
context.CommandTimeout = 120
// Specify a timeout for queries in this context, in seconds.
context.CommandTimeout = 120;

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

Просмотр команд хранилища

При выполнении запроса к модели EDM в Entity Framework происходит преобразование запроса LINQ to Entities и запроса Entity SQL, основанного на модели EDM, в эквивалентный запрос к источнику данных. В службах объектов предоставляется метод ToTraceString, который позволяет просматривать эти команды хранилища, относящиеся к запросу ObjectQuery, во время выполнения, без необходимости выполнения трассировки по отношению к источнику данных. В поставщике EntityClient предусмотрен также метод ToTraceString объекта EntityCommand. Дополнительные сведения см. в разделе Как просмотреть команды хранения (платформа Entity Framework).

Выборка объекта по его значению EntityKey

Если известно значение ключа сущности, то ее можно получить из источника данных без явного создания и выполнения запроса объектов. Методы GetObjectByKey и TryGetObjectByKey объекта ObjectContext возвращают объект с указанным значением EntityKey в контекст объекта. Если используется метод GetObjectByKey, то необходимо обрабатывать исключения ObjectNotFoundException, возникающие, если предоставленное значение EntityKey не соответствует ни одной из существующих сущностей. Дополнительные сведения см. в разделе Как выполнить возврат конкретного объекта с использованием его ключа (Entity Framework).

См. также

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

Запросы к данным как к объектам (платформа Entity Framework)