有人可以回答我如何在不多次保存数据的情况下使用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);
}
这是我的User,Group和它们之间的联接表的模型:
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; }
}
...
}
答案 0 :(得分:1)
是这样吗?
可能,但是开销最小的方法始终是使用DbSet<GroupMember>
。 (建议:不要使用复数类名)。然后,您只需要两个ID值:
var groupMember = new GroupMember
{
GroupId = groupId,
UserId = userId
};
_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();
这可以嵌入到任何用例中。您可能会遇到以下情况:从UI或API仅提供ID值,或者以User
或Group
为起点,同时提供一个ID值和另一部分的ID值提供。一切都归结为这段小代码。
答案 1 :(得分:0)
我认为efcore tracker可以处理这种情况,并且不会两次插入记录。如果没有,则可以将groupmember对象一次插入数据库中,而不用同时更新组和用户。在性能上也更好,因为只需要一个查询。
答案 2 :(得分:0)
不是真的,组成员的数据将被保存两次,例如。冗余吗?
不。您可以在GroupMember上正确设置密钥,以防止出现这种情况:
builder.Entity<GroupMembers>().HasKey(gm => new { gm.UserId, gm.GroupId });