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

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

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

  • Типы CLR, поддерживаемые концептуальной моделью.

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

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

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

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

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

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

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

public static int count = 0;

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

        var query1 = AWEntities
           .Contacts
           .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
           .Contacts
           .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 count As Integer = 0

Sub Main()

    Using AWEntities As New AdventureWorksEntities()

        Dim query1 = AWEntities.Contacts _
        .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 _
        .Contacts() _
        .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 class MyContact
{

    String _lastName;

    public string LastName
    {
        get
        {
            return _lastName;
        }

        set
        {
            _lastName = value;
            count++;
        }
    }
}
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