How to avoid redundancy/save data in EF Core many-to-many relationships?

asp.net c# ef-core-2.1 entity-framework-core

Question

Can someone please answer me how to properly add and insert data into a join table/many-to-many relationship with Entity Framework Core, without saving data multiple times?

My Database Context looks like this with Fluent API:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>().HasIndex(u => u.Username).IsUnique(true);

     builder.Entity<GroupMembers>().HasKey(gm => new { gm.UserId, gm.GroupId });
     builder.Entity<GroupMembers>().HasOne(gm => gm.Group).WithMany(group.GroupMembers).HasForeignKey(gm => gm.GroupId);
     builder.Entity<GroupMembers>().HasOne(gm => gm.User).WithMany(user.GroupMembers).HasForeignKey(gm => gm.UserId);
}

Here are my models for User, Group and the join table between them:

public class User
{
    [Key]
    public Guid Id { get; set; }
    public string Username { get; set; }
    public List<GroupMembers> GroupMembers { get; set; } = new List<GroupMembers>();
}
public class Group
{
    [Key]
    public Guid Id { get; set; }
    public string GroupName { get; set; }
    public List<GroupMembers> GroupMembers { get; set; } = new List<GroupMembers>();
}
public class GroupMembers
{
    [Key]
    public Guid UserId { get; set; }
    public User User { get; set; }

    [Key]
    public Guid GroupId { get; set; }
    public Group Group { get; set; }
}

Now, the question is; how do I add a relationship between them/insert into the tabel GroupMembers? Is it like this?

public class DatabaseHelper : IDatabaseHelper
{
    private readonly AppDatabaseContext _databaseContext;

    private readonly AppDatabaseContext _databaseContext;

    GroupMembers groupMember = new GroupMembers
    {
        Group = group,
        GroupId = group.Id,
        User = user,
        UserId = user.Id
    };

    User user = ...
    Group group = ...

    user.GroupMembers.Add(groupMember);
    group.GroupMembers.Add(groupMember);

    _databaseContext.Users.Update(user);
    _databaseContext.Groups.Update(group);
    _databaseContext.SaveChanges();
}

If this is the correct solution, then isn´t it true that the data for group members will be saved two times eg. redundancy? Group has the information about its members, and User has information about its group memberships. With a normal RDBS the information about the memberships are saved in the join tables, namely GroupMembership only once, without any redundancy. How do I do this with EF Core many-to-many?

EDIT Should GroupMembers be a DbSet<>, or should only User and Group be a DbSet<>?

public class AppDatabaseContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Group> Groups { get; set; }
        //public DbSet<GroupMembers> GroupMembers{ get; set; }
    }
    ...
}
1
0
10/20/2019 10:29:23 AM

Popular Answer

Is it like this?

Possibly, but the method with the least overhead is always to have a DbSet<GroupMember>. (Advice: don't use plural class names). Then all you need is two ID values:

var groupMember = new GroupMember
{
    GroupId = groupId,
    UserId = userId
};

_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();

This can be embedded in any use case. You may have cases where only ID values are supplied from a UI or an API, or where either a User or a Group is the starting point, supplying one ID value, and ID values of the other part are supplied. It all boils down to this little piece of code.

1
10/20/2019 2:58:29 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow