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


Результаты запроса

После преобразования запроса LINQ to Entities в деревья команд и последующего выполнения результаты запроса обычно возвращаются в одной из следующих форм.

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

  • Типы CLR, поддерживаемые моделью EDM.

  • Встроенные коллекции.

  • Анонимные типы.

При выполнении запроса к источнику данных результаты материализуются в типы CLR и возвращаются клиенту. Материализация объектов полностью обеспечивается платформой Entity Framework. Любые ошибки, вызванные невозможностью сопоставления объектов платформы Entity Framework и среды CLR, вызовут исключения во время материализации объекта.

Если в результате выполнения запроса возвращаются типы-примитивы модели EDM, то результаты состоят из изолированных типов CLR, которые не соединены с платформой Entity Framework. Однако если запрос вернул коллекцию типизированных объектов сущностей, представленных ObjectQuery, то эти типы отслеживаются контекстом объекта. Все операции с объектом (дочерние и родительские коллекции, отслеживание изменений, полиморфизм и т. д.) выполнятся согласно определениям Entity Framework. Эти функции можно могут быть использованы в пределах, определяемых Entity Framework. Дополнительные сведения см. в разделе Общие сведения о службах объектов (платформа Entity Framework).

Типы структур, возвращаемые из запросов (например, анонимные и сложные типы, допускающие значение NULL), могут иметь значение null. Свойство EntityCollection возвращаемой сущности также может иметь значение null. Это может произойти в результате проецирования свойства коллекции для сущности, имеющей значение null, например, при вызове метода FirstOrDefault для объекта ObjectQuery, который не содержит элементов.

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

В следующем примере имеется пользовательский класс MyContact со свойством LastName. При присваивании значения свойству LastName переменная count увеличивается на единицу. Если выполнить два приведенных ниже запроса, то первый запрос увеличит значение count на единицу, а второй — нет. Причина этого заключается в том, что во втором запросе свойство LastName спроецировано из результатов, а класс MyContact не создается, поскольку он не является необходимым для выполнения запроса в хранилище.

Public count As Integer = 0

Sub Main()

    Using AWEntities As New AdventureWorksEntities()

        Dim query1 = AWEntities.Contact _
        .Where(Function(c) c.LastName = "Jones") _
        .Select(Function(c) New MyContact With {.LastName = c.LastName})

        ' Execute the first query and print the count.
        query1.ToList()
        Console.WriteLine("Count: " & count)

        ' Reset the count variable.
        count = 0

        Dim query2 = AWEntities _
        .Contact() _
        .Where(Function(c) c.LastName = "Jones") _
        .Select(Function(c) New MyContact With {.LastName = c.LastName}) _
        .Select(Function(x) x.LastName)

        ' Execute the second query and print the count.
        query2.ToList()
        Console.WriteLine("Count: " & count)

    End Using
End Sub
public static int count = 0;

static void Main(string[] args)
{
    using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
    {

        var query1 = AWEntities
           .Contact
           .Where(c => c.LastName == "Jones")
           .Select(c => new MyContact { LastName = c.LastName });

        // Execute the first query and print the count.
        query1.ToList();
        Console.WriteLine("Count: " + count);

        //Reset the count variable.
        count = 0;

        var query2 = AWEntities
           .Contact
           .Where(c => c.LastName == "Jones")
           .Select(c => new MyContact { LastName = c.LastName })
           .Select(my => my.LastName);

        // Execute the second query and print the count.
        query2.ToList();
        Console.WriteLine("Count: " + count);

    }

    Console.WriteLine("Hit enter...");
    Console.Read();
}
Public Class MyContact

    Private _lastName As String

    Public Property LastName() As String
        Get
            Return _lastName
        End Get

        Set(ByVal value As String)
            _lastName = value
            count += 1
        End Set
    End Property

End Class
public class MyContact
{

    String _lastName;

    public string LastName
    {
        get
        {
            return _lastName;
        }

        set
        {
            _lastName = value;
            count++;
        }
    }
}

См. также

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

Выполнение запросов с помощью LINQ to Entities