Результаты запроса
После преобразования запроса 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