Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

109
Views
EF Core DDD Many-to-many

I'm trying to follow DDD using EF Core and in my model I have the following:

    private List<TeamPerson> _personLinks;
    
    public IReadOnlyCollection<TeamPerson> PersonLinks => _personLinks?.ToList().AsReadOnly();

    public IReadOnlyCollection<Person> Members => _personLinks?.Select(l => l.Person).ToList().AsReadOnly();

I want to encapsulate the relationship between Team and Person models. I must say right away that there is a mapping for the Person model and it works.

But if I specify property access mode:

builder.HasMany(e => e.PersonLinks)
   .WithOne(e => e.Team)
   .HasForeignKey(e => e.TeamId)
   .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field);

builder.HasMany(e => e.TeamLinks)
   .WithOne(e => e.Person)
   .HasForeignKey(e => e.PersonId)
   .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field);

And if I try to get dbContext.Teams.Include(t => t.PersonLinks).ThenInclude(t => t.Person), I'm getting an error: "...PersonId1 column doesn't exist...", I have this for TeamPerson model mapping:

builder.Property(e => e.PersonId).IsRequired().HasColumnName("person_id");

What is my mistake or is there any other way to reach the encapsulation for the collection here?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

I think you need to configure a one-to-many relationship between both Person and PersonLinks as well between Team and PersonLinks to achieve the many-to-many relationship.

builder.Entity<PersonLink>()
    .HasKey(personLink => new { personLink.TeamId, personLink.PersonId });

builder.Entity<PersonLink>()
    .HasOne<Team>(personLink => personLink.Team)
    .WithMany(team => team.PersonLinks)
    .HasForeignKey(personLink => personLink.TeamId);

builder.Entity<PersonLink>()
    .HasOne<Person>(personLink => personLink.Person)
    .WithMany(person => person.PersonLinks)
    .HasForeignKey(personLink => personLink.PersonId);

This of course will only work if your PersonLink class looks something like this:

public class PersonLink
{
    public int PersonId { get; set; }
    public Person Person { get; set; }

    public int TeamId { get; set; }
    public Team Team { get; set; }
}

For the id data types I assumed a simple int which could be string or GUID (or even some custom type in your code) but I think this is not that important here.

Note: I could not resist to rename PersonLinks to PersonLink it feels more natural to me because the class represents one person link between Team and Person from my point-of-view. Also, I know it somehow a convention to use abbreviated parameter names for lambda expressions but I think, especially in this case, it is easier to read instead of using p (for Person) and pl (for PersonLink) - maybe it's just a matter of taste in this case...

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!