EF Code First Lazy loading Not Working

15,741

Solution 1

I realized that the problem was that the Merchant class did not meet requirements for proxy generation. Specifically, I needed to add a protected parameterless constructor. I only had a private one.

Solution 2

Another thing that can cause lazy loading to fail is navigation properties that are not virtual. That was not the case for OP, but this question is a top Google result so it may help some.

And yet another possible cause is a mapped database column that doesn't exist. I was surprised to see that break lazy loading rather than throw a database exception.

Share:
15,741
user1032657
Author by

user1032657

Updated on June 28, 2022

Comments

  • user1032657
    user1032657 almost 2 years

    I am using code first with EF6 but cannot seem to get lazy loading to work. Eager loading is working fine. I have the following classes:

    public class Merchant : User
    {
        ...
    
        public virtual ICollection<MerchantLocation> MerchantLocations { get; set; }
    }
    
    public class MerchantLocation : BaseEntity
    {
        ...
    
        public int MerchantId { get; set; }
        public virtual Merchant Merchant { get; set; }       
    }
    
    public class User : BaseEntity
    {
        ...
    }
    
    public class BaseEntity
    {
        ...
    
        public int Id { get; set; }
    }
    

    I test my lazy loading of the locations via the following code (which fails):

    public void Test_Lazy_Loading() {
        using (var context = new MyDbContext()) {
            var merchant = context.Users.OfType<Merchant>.First();
            merchant.MerchantLocations.ShouldNotBeNull(); // fails
        }
    }
    

    However eager loading works fine:

    public void Test_Eager_Loading() {
        using (var context = new MyDbContext()) {
            var merchant = context.Users.OfType<Merchant>.Include("MerchantLocations").First();
            merchant.MerchantLocations.ShouldNotBeNull(); // passes
        }
    }
    

    MerchantLocations is marked as public virtual so I'm not sure what the problem is. I have also added the following in my DbContext constructor:

    Configuration.LazyLoadingEnabled = true;
    Configuration.ProxyCreationEnabled = true;
    

    edit: I have also noticed that the merchant object being returned in the above tests is not an EF proxy. It is a plain Merchant. I suspect that this is causing the problem.