Home > Software engineering >  EF won't load data from many to many relationship
EF won't load data from many to many relationship

Time:11-06

public class A
{
    public string Name { get; set }
    public ICollection<B> b { get; set; }
}

public class B
{
    public string Name { get; set }
    public ICollection<A> a { get; set; }
}

Since .NET 5.0 we don't need to create a join class, my data has been successfully inserted into tables A and B as well as the join table (which has PK for A and B).

But when I try to retrieve data like:

DBConext.A.b.count

I get 0. I double-checked my database and found data is there, both tables A, B, and the join table AB, I know this probably a small issue, someone please help me

CodePudding user response:

You need to use Include method to specify related data to be included in query results. But you cannot simply using DBContext.A.Include(a => a.b).b.count to get the count. Due to your two tables contain many-to-many relationship.

If you want to get specific A class's(by specific id or name...) related B class count, you can use:

public class TestController : ControllerBase
{
    private readonly Dotnetcore5_0Context _context;

    public TestController(Dotnetcore5_0Context context)
    {
        _context = context;
    }
    [HttpGet]
    public void Get()
    {
        //get the count of B class if A's Name equals to aa
        var data = _context.A.Include(a => a.b)
                             .Where(a=>a.Name=="aa").ToList()
                             .Select(a => a.b.Count()).ToList();

    }
}

If you want to get all the A class's related B class count, you can use:

public class TestController : ControllerBase
{
    private readonly Dotnetcore5_0Context _context;

    public TestController(Dotnetcore5_0Context context)
    {
        _context = context;
    }
    [HttpGet]
    public void Get()
    {
        var data = _context.A.Include(a => a.b).ToList()
                             .Select(a => a.b.Count()).ToList();

    }
}

CodePudding user response:

Additionally to Rena answer, you can simplify a lot of things if you use lazy proxies.

In DbContext, add following:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseLazyLoadingProxies();
    ...
} 

This is may be useful when you're fetching relations for one/two entities. If you want to load relations for many objects, it's better to use Include, because data will load from one DB request, not hundreds.

  • Related