akdemirsafak
akdemirsafak

Reputation: 7

Entity Framework Core LazyLoading returning null

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

Upvotes: 0

Views: 235

Answers (2)

mostafa aghili
mostafa aghili

Reputation: 102

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

Upvotes: -1

Mohsen Esmailpour
Mohsen Esmailpour

Reputation: 11544

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

Upvotes: 1

Related Questions