如何避免冗余/在EF 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; }
}

现在,问题是;如何在它们之间添加关系/插入到工作表组成员中? 是这样的吗?

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,有关成员资格的信息仅保存在连接表中,即组成员资格仅保存一次,没有任何冗余。 如何使用 EF Core 多对多执行此操作?

编辑组成员应该是 DbSet<>,还是只有用户和组是 DbSet<>?

public class AppDatabaseContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Group> Groups { get; set; }
//public DbSet<GroupMembers> GroupMembers{ get; set; }
}
...
}

是这样的吗?

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

var groupMember = new GroupMember
{
GroupId = groupId,
UserId = userId
};
_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();

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

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

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

不。 您在 GroupMember 上正确设置了密钥以防止:

builder.Entity<GroupMembers>().HasKey(gm => new { gm.UserId, gm.GroupId });

最新更新