0

I working a project and i need use lazyloading i installed package and configure,query working but relationship columns returned null. How to i can use lazyloading?

Installed Microsoft.EntityFrameworkCore.Proxies(version 5.0.7)

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer("ConnectionString");
                optionsBuilder.UseLazyLoadingProxies(true);

            }
        }

My Models(I make with DB First)

 public partial class Customer
    {
        public Customer()
        {
            Orders = new HashSet<Order>();
         
        }

        public int CustomerId { get; set; }
        public int? CompanyId { get; set; }
        public string Name { get; set; }
        public string LastName { get; set; }
        public string FullName { get; set; }
        public string Phone { get; set; }
        public string Mail { get; set; }

        virtual public Company Company { get; set; }
        virtual public ICollection<Order> Orders { get; set; }
    }
    
public partial class Company
    {
        public Company()
        {
            Customers = new HashSet<Customer>();
        }

        public int CompanyId { get; set; }
        public string Name { get; set; }
        public string TaxNumber { get; set; }

        public virtual ICollection<Customer> Customers { get; set; }
    }

Used Method:

public List<Customer> GetCustomers()
        {
            using (dbContext context = new dbContext())
            {
               return context.Customers.ToList();
            }
        }
1
  • The visible code doesn't give any reason to think that lazy loading wouldn't work, and unfortunately it's not clear where you have a problem. What's the meaning of "relationship columns returned null"? Commented Nov 27, 2023 at 11:52

2 Answers 2

1

According to the documentation, lazy loading should be implemented in this way

Install Microsoft.EntityFrameworkCore.Abstractions package too and change the implementation:

public partial class Customer
{
    private ICollection<Orders> _orders;

    public Customer()
    {
        Orders = new HashSet<Order>();
    }

    public Customer(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    private ILazyLoader LazyLoader { get; set; }

    public int CustomerId { get; set; }
    public int? CompanyId { get; set; }
    public string Name { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }
    public string Phone { get; set; }
    public string Mail { get; set; }

    virtual public Company Company { get; set; }

    public ICollection<Order> Orders
    {
        get => LazyLoader.Load(this, ref _orders);
        set => _orders = value;
    }
}

And after iterating on orders data will be fetched

using(var db = new YourContext())
{
    var customers = db.Customers.ToList();
    foreach(var customer in customers )
    {
        Console.WriteLine($"Customer: {customer.Name} {customer .LastName}");
        foreach(var order in customer.Ortders) // lazy loading initiated
        {
            Console.WriteLine($"\t{order.Id}");
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

thank you for help, I remake and I have a exception: Castle.DynamicProxy.InvalidProxyConstructorArgumentsException HResult=0x80070057 Message=Can not instantiate proxy of class: MyProjectName.Models.Customer. Could not find a constructor that would match given arguments: Microsoft.EntityFrameworkCore.Internal.LazyLoader
I update the answer and check it again, please.
-1

Better way to use lazy load is that , we used Lazy loading without proxies, according to Microsoft document Lazy loading without proxies.

When EF try to create object from your class ,It call your model constructor that have no argument ,then lazyLoader service did not fill. you most remove empty constructor And just keep that one with lazyLoader:

public Customer(ILazyLoader lazyLoader)
{
    LazyLoader = lazyLoader;
}

Your model class most be like this :

public partial class Customer
{
    private ICollection<Orders> _orders;
    private ILazyLoader LazyLoader { get; set; }

    public Customer(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }
 
    public int CustomerId { get; set; }
    public int? CompanyId { get; set; }
    public string Name { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }
    public string Phone { get; set; }
    public string Mail { get; set; }

    public Company Company { get; set; }

    public ICollection<Order> Orders
    {
        get => LazyLoader.Load(this, ref _orders);
        set => _orders = value;
    }
}

1 Comment

This doesn't answer the question. It's an alternative and certainly not objectively "better".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.