2015-07-22 9 views
4

У меня есть класс poco, который подключен к инфраструктуре сущности. Класс называется PersonalizationCatalogPrice. Этот класс имеет подэлемент, называемый Pricelevel, который не имеет на нем виртуального ключевого слова. Из-за этого (на основе моего понимания) этот объект никогда не должен лениться и должен возвращать значение null. Однако мы обнаружили, что этот объект, похоже, загружается при его использовании определенным образом.Entity framework 6 ленивая загрузка oddity

поэтому базовая структура класса это

public class PersonalizationCatalogPrice 
    { 
     public int PersonalizationCatalogPriceID { get; set; } 

     public int PersonalizationCatalogId { get; set; } 

     public virtual PersonalizationCatalog PersonalizationCatalog { get; set; } 

     public decimal CustomerRetail { get; set; } 

     public decimal ConsultantCost { get; set; } 

     public decimal PersonalVolume { get; set; } 

     public decimal QualifyingVolume { get; set; } 

     public int PriceLevelId { get; set; } 

     public PriceLevel PriceLevel { get; set; } 
} 

Ниже приведен пример. В первой строке мы возвращаем элементы Iqueryable of PersonalizationCatalogPrice. Во второй строке есть еще один IQueryable, и мы используем объект priclevel в этом iQueryable (см. Строку «содержит pcp.pricelevel»). Когда мы это делаем, объект pricelevel загружается, даже если у него нет виртуального ключевого слова.

IQueryable<PersonalizationCatalogPrice> allPersPriceRecords = _e2ReposMan.PersonalizationRepository.GetSomeRecords(); 

//List<PersonalizationCatalogPrice> persprices = allPersPriceRecords.ToList(); 

var persQuery = from pl in personalizationLines 
       join pcp in allPersPriceRecords on pl.Item2.PersonalizationCatalogPriceID equals pcp.PersonalizationCatalogPriceID 
       where !HostessPriceLevelTypes().Contains(pcp.PriceLevel.PriceLevelTypeId) 
       select pl.Item2.PersonalVolume * pl.Item1; 

var openOrdersTotal = (query.Any() ? query.Sum() : 0) + (persQuery.Any() ? persQuery.Sum() : 0); 

Изменение этого кода путем раскодирования второй строки, которая выполняет только ToList(). Делает подобъект уровня цены возвратом null как ожидалось, так как на нем нет виртуального ключевого слова, а структура сущности работает, как мы и ожидаем. (EF 6)

Кто-нибудь знает, почему мы можем загрузить свойство уровня цены, когда мы не делаем toList().

благодарит за любую помощь.

+1

«Ценовой уровень, на котором нет виртуального ключевого слова. Из-за этого (на основе моего понимания) этот объект никогда не должен лениться» - виртуальная используется для ленивой загрузки. Вам также необходимо проверить свой контекст LazyLoadingEnabled. Наконец, вы получаете доступ к PriceLevel в своем запросе, чтобы он не загружался? Может быть, им непонятно по этому вопросу. https://msdn.microsoft.com/en-us/data/jj574232.aspx#lazy –

+0

Должно быть, если вы определили его как виртуальный, которого у нас нет. Из-за этого должно быть null. Если я добавлю виртуальную в нее, тогда она должна загружаться при ее доступе. Это «ленивая нагрузка» .. не загружается, пока это не понадобится.Но это свойство загружается, когда к нему обращаются, как если бы он был определен как виртуальное свойство, а это не так. Кроме того, наш контекст разрешает ленивую загрузку. – Matt

+0

Имущество собирается «загружать» при доступе, является ли он ленивым (виртуальным) или нет. Ленькая часть запускается, если она виртуальна, ленивая загрузка включена и вы никогда не получаете доступ к собственности. –

ответ

1

Основываясь на используемой вами формулировке, вы ожидаете, что PriceLevel должно быть null, если вы не используете ленивую загрузку.

Есть некоторые случаи, о которых я могу думать, в которых это ожидание не будет выполнено.

Первый случай будет, если вы загружаете данные с нетерпением. Который будет явно использовать Include(). Такое поведение также называется нетерпеливой загрузкой. Поскольку загруженная загрузка действительно загружает все, что ей разрешено, она не требует, чтобы вы перечисляли коллекцию, вызывая ToArray() или ToList() или другие методы, которые запускают перечисление. Будут загружены все свойства, которые не являются ленивыми, включая все его свойства типа значения и свойства, отличные от лени.

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

То же самое было бы верно, если бы вы загрузили этот объект явно, вызвав Load() или если он был возвращен из какого-либо другого предыдущего запроса.

Чтобы проверить, действительно ли это так, вы можете использовать метод расширения AsNoTracking(). Сущности, которые не отслеживаются, будут, среди других эффектов, не связаны друг с другом.

Смежные вопросы