Search code examples
c#asp.netentity-framework-coreef-code-first

EF Code First design of entity relationships


I have 3 entities, User, League and Team. I have the following requirements :

A User-League combination can have only 1 team.

League-Team combination can have only 1 user.

User-Team combination can have multiple leagues.

So these would be valid combinations :

User League Team
1    1      1
1    2      2
1    3      1
2    1      2
2    2      1
3    1      3
3    3      2

What would be the best way to achieve this in EF Code First? Would it be better to create one join table with Users-Leagues-Teams, or multiple join tables eg Users-Leagues, Users-Teams, Leagues-Teams? And what would be the best way to enforce the above requirements?

Thanks in advance.

EDIT :

With the suggestion of Roberto, I now have this entity :

public class UserLeagueTeam {

    public int UserId { get; set; }

    public ApplicationUser? User { get; set; }

    public int LeagueId { get; set; }   

    public League? League { get; set; } 

    public int TeamId { get; set; } 

    public Team? Team { get; set; }
}

And in the builder it looks like this :

public class UserLeagueTeamTypeConfiguration : IEntityTypeConfiguration<UserLeagueTeam>
{
    public void Configure(EntityTypeBuilder<UserLeagueTeam> builder)
    {
        builder.ToTable("UserLeagueTeam");
        builder.HasKey(u => new { u.UserId, u.LeagueId, u.TeamId });
        builder.HasIndex(x => new { x.UserId, x.LeagueId }).IsUnique();
        builder.HasIndex(x => new { x.LeagueId, x.TeamId }).IsUnique();
    }
}

Would this be the correct way to go about this?


Solution

  • I suggest to use an explicit entity to manage the relation, something like the following:

    public class UserLeagueTeamRelation {
        public int UserId { get; set; }
    
        public User? User { get; set; }
    
        public int LeagueId { get; set; }   
    
        public League? League { get; set; } 
    
        public int TeamId { get; set; } 
    
        public Team? Team { get; set; }
    }
    

    And then set unique indexes in the builder:

    public class UserLeagueTeamRelationTypeConfiguration : IEntityTypeConfiguration<UserLeagueTeamRelation> {
        public void Configure(EntityTypeBuilder<UserLeagueTeamRelation> builder) {
            // ...
            builder.HasIndex(x => new { x.UserId, x.LeagueId }).IsUnique();
            builder.HasIndex(x => new { x.LeagueId, x.TeamId }).IsUnique();
            // ...
        }
    }