如何避免在EF Core多对多关系中进行冗余/保存数据?

问题描述 投票:0回答:3

有人可以回答我如何使用Entity Framework Core将数据正确添加和插入到联接表/多对多关系中,而又不保存数据的情况吗?

使用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);
}

这是我的用户,组和它们之间的联接表的模型:

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; }
}

现在,问题是;如何将它们之间的关系/插入到Tabel GroupMembers中?像这样吗?

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();
}

如果这是正确的解决方案,那么组成员的数据将被保存两次,这不是真的吗?冗余?组具有有关其成员的信息,而用户具有有关其组成员的信息。对于普通的RDBS,有关成员资格的信息仅保存在联接表中,即GroupMembership,一次,没有任何冗余。如何使用EF Core多对多功能?

编辑GroupMembers应该是DbSet <>,还是只有User和Group是DbSet <>?

public class AppDatabaseContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Group> Groups { get; set; }
        //public DbSet<GroupMembers> GroupMembers{ get; set; }
    }
    ...
}
c# asp.net entity-framework-core ef-core-2.1
3个回答
1
投票

是这样吗?

可能,但是开销最小的方法总是具有DbSet<GroupMember>。 (建议:不要使用复数类名)。然后,您只需要两个ID值:

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

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

这可以嵌入到任何用例中。您可能会遇到以下情况:从UI或API仅提供ID值,或者以UserGroup为起点,提供一个ID值,而提供另一部分的ID值。一切都归结为这段小代码。


0
投票

我认为efcore跟踪器会处理这种情况,不会两次插入记录。如果没有,则可以将groupmember对象一次插入数据库中,而不用同时更新组和用户。这也是更好的性能选择,因为只需要一个查询。


0
投票

不是真的,组成员的数据将被保存两次,例如。冗余?

没有您可以在GroupMember上正确设置密钥,以防止出现以下情况:

builder.Entity<GroupMembers>().HasKey(gm => new { gm.UserId, gm.GroupId });
© www.soinside.com 2019 - 2024. All rights reserved.