Entity Framework, при вызове ToList () он будет загружать объекты FK автоматически? - PullRequest
3 голосов
/ 20 января 2012

Я немного озадачен тем, как работает Ленивая загрузка.

Например, если у меня есть объект поставщика, у которого в качестве свойства указан внешний объект Address, например:

public class Supplier
{
        public int ID { get; set; }
        [Required]
        public string FullName { get; set; }
        public string TaxNumber { get; set; }
        public virtual Address DeliveryAddress { get; set; }
}

когда я ставлю точку останова на:

var suppliers = dbContext.Supplier.ToList();

Я вижу, что информация об адресе доступна поставщикам var и т. Д. Когда я расходую свойство DeliveryAddress, оно доступно, означает ли это, что весь объект FK был загружен? Но с другой стороны, для запроса справа я могу просмотреть его из Visual Studio в точке останова, и это так:

{SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[FullName] AS [FullName], 
[Extent1].[TaxNumber] AS [TaxNumber], 
[Extent1].[DeliveryAddress_ID] AS [DeliveryAddress_ID]
FROM [dbo].[Suppliers] AS [Extent1]}

Что означает, что сам запрос вообще не будет загружать объект Address?

Так, кто загружает объекты FK? ToList () или VS отладчик?

Другое предложение о том, как подтвердить, что это ленивая загрузка или нет?

Примечание: Итак, теперь я подтвердил, что отложенная загрузка работает двумя вызовами ToList: один отключил отложенную загрузку, а другой включил отложенную загрузку. Может кто-нибудь указать мне способ узнать, в какой момент при отложенной загрузке был отправлен другой запрос для свойства FK?

1 Ответ

6 голосов
/ 20 января 2012

Отладчик VS загружает связанный объект, и это происходит со вторым запросом SQL, а не с тем, который вы показали в своем вопросе.Когда вы углубляетесь в объект адреса в отладчике, отладчик обращается к свойствам объекта, чтобы отобразить их значения.Доступ к этому объекту запускает отложенную загрузку и второй запрос SQL.

Редактировать

Это работает, потому что родительский объект не является вашим типом Supplier, а классом, который является производнымот Supplier («прокси»).Этот производный класс создается динамически во время выполнения и имеет какое-то загадочное автоматически сгенерированное имя (вы должны увидеть это имя класса в отладчике).Этот динамический класс имеет те же свойства, что и ваш базовый Supplier, но он перегружен свойством DeliveryAddress.(По этой причине эти свойства навигации должны быть virtual, в противном случае перегрузка была бы невозможна.) В запросе используется значение столбца FK, которое уже было получено в запросе поставщика, и извлекает адрес по этому значению.

Новый метод получения перегруженного свойства DeliveryAddress, которое вызывается, когда вы или отладчик обращаетесь к свойству с помощью supplier.DeliveryAddress, содержит во время выполнения сгенерированный код, который выполняет запрос SQL для загрузки связанного объекта из базы данных.Производный прокси-класс содержит различные дополнительные внутренние члены, особенно ссылку на соединение контекста / базы данных (чтобы вообще иметь возможность выполнить запрос) и флаг, указывающий для прокси-объекта, что он уже загрузил свойство навигации, так чтоон не запускает второй избыточный запрос, когда вы обращаетесь к DeliveryAddress во второй раз.

Короче говоря, как работает отложенная загрузка с POCO.

...