Steve McNiven-Scott
Steve McNiven-Scott

Reputation: 1902

Populating Many-Many Navigation Properties in EF Core

I am unsure how to define Include(..).ThenInclude(...) in the context of a many->many relationship.

So this is populating the nav property, SiteEducators is the link

var site = this._dbContext.Sites.Include(x => x.SiteEducators).FirstOrDefault();

Defined per the docs

    public DbSet<Educator> Educators { get; set; }
    public DbSet<Site> Sites { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        #region Site->Educator Link
        modelBuilder.Entity<SiteEducator>()
           .HasKey(t => new { t.SiteId, t.EducatorId });

        modelBuilder.Entity<SiteEducator>()
            .HasOne(pt => pt.Site)
            .WithMany(p => p.SiteEducators)
            .HasForeignKey(pt => pt.SiteId);

        modelBuilder.Entity<SiteEducator>()
            .HasOne(pt => pt.Educator)
            .WithMany(t => t.SiteEducators)
            .HasForeignKey(pt => pt.EducatorId);
        #endregion
    }

Problem is if I debug "site" it HAS the navigation property and I can see the value of "EducatorId" just fine, but IT'S navigation property down to Educator is null.

So this would be null

model.SiteEducators.FirstOrDefault().Educator

Where this would return a value

model.SiteEducators.FirstOrDefault().EducatorId

Example of what I mean:

enter image description here

enter image description here

There has to be some sort of "ThenInclude" on the array?

How do I flesh out this other object, whats the synatax, any idea?

Any help would be great, thx guys :)

Upvotes: 1

Views: 390

Answers (1)

Steve McNiven-Scott
Steve McNiven-Scott

Reputation: 1902

Okay so it looks like it's a series of git issues, this is the fix:

1) Map your link table object in your ApplicationDbContext.

public DbSet<SiteEducator> SiteEducator { get; set; }

(Sidenote: Didnt pluralize it because the DB table that was generated from just the regular Many->Many setup didn't pluralize it, didnt want to duplicate anything just in case)

2) Now AFTER your initial query, run a second query to load the data items. You dont have to assign them anywhere EF should just now know they are loaded in the root object

var site = this._dbContext.Sites
               .Include(x => x.SiteEducators)
               .Include(x => x.Studies)
               .FirstOrDefault(x => x.SupervisorToken == key);


//Dummy query to load the data
this._dbContext.SiteEducator.Include(x => x.Educator).Where(x => x.SiteId == site.Id).Load();

The problem is the docs leave out the important part of mapping the link table in, without that there doesnt seem to be a way to load the nested objects in the List.

Upvotes: 1

Related Questions