简体   繁体   中英

Entity framework 6 lazy loading oddity

I have a poco class which is wired up to the entity framework. The class is called PersonalizationCatalogPrice. This class has a sub object called Pricelevel which does not have the virtual keyword on it. Because of this (based on my understanding) this object should never lazy load and should return null. However, we have found that this object seems to load up when used in a specific manner.

so the basic class structure is this

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; }
}

Here is an example. In the first line we return an Iqueryable of PersonalizationCatalogPrice items. In the second line we have another IQueryable and we are using the priclevel object in this iQueryable (see the line "contains pcp.pricelevel"). When we do this, the pricelevel object loads up even though it has no virtual keyword.

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);

Modifying this code by uncommenting the second line which performs a ToList() however. Makes the pricelevel subobject return null as expectedd since it does not have a virtual keyword on it and the entity framework then works as we anticipate. (EF 6)

Does anyone know why we are able to load the pricelevel property when we do not do the toList().

thanks for any assistance.

Based on the wording you used, it appears that you expect the PriceLevel property to be null when not using lazy loading.

There are some cases i can think of, in which this expectation would not be met.

The first case would be if you are loading the data in a eager way. Which would be explicitly using Include() . This behaviour is also called eager loading. Since eager loading does load everything it is allowed to, it does not require you to enumerate the collection by calling ToArray() or ToList() or other methods that trigger enumeration. Every property which is not lazy will be loaded, that includes all its value type properties and non-lazy properties.

Your code does not indicate this, however the property would still not be null if you did this on the same DbContext derived instance before executing the code you displayed. This would happen whenever the entity in question already resides cached in your DbContext.

The same would be true if you had loaded that entity explicitly by calling Load() or if it had been returned from some other previous query.

In order to verify whether this is the case or not you can use the AsNoTracking() extension method. Entities which are not tracked will, among other effects, not be linked with each other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM