EF Core 删除多对多关系中的数据

EF Core delete data in many to many relationship

我有以下表格:

public class Team 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<UserTeam> UserTeams { get; set; }
}

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<UserTeam> UserTeams { get; set; }
}

public class UserTeam
{
    public long UserId { get; set; }
    public User User { get; set; }

    public long TeamId { get; set; }
    public Team Team { get; set; }
}

多对多关系在上下文中定义:

modelBuilder.Entity<UserTeam>()
    .HasKey(bc => new { bc.UserId, bc.TeamId });

modelBuilder.Entity<UserTeam>()
    .HasOne(bc => bc.User)
    .WithMany(b => b.UserTeams)
    .HasForeignKey(bc => bc.UserId)
    .OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<UserTeam>()
    .HasOne(bc => bc.Team)
    .WithMany(c => c.UserTeams)
    .HasForeignKey(bc => bc.TeamId)
    .OnDelete(DeleteBehavior.Restrict);

我正在尝试使用以下代码从团队中删除一些用户:

public async Task RemoveUsersFromTeam(int teamId, List<long> users)
{
    Team existingTeam = await dbContext.Team.Include(x => x.UserTeams).FirstOrDefaultAsync(x => x.Id == teamId);
    foreach (var user in users)
    {
        existingTeam.UserTeams.Remove(new UserTeam { UserId = user });
    }

    await dbContext.SaveAsync();
}

但是这个查询并没有删除我通过的用户。有人知道为什么会这样吗?

您可以使用 new 和 attach 方法按 Id 删除对象,或者传递实际实体。

路过实体

public async Task RemoveUsersFromTeam(int teamId, List<long> userIds)
{
    Team existingTeam = await dbContext.Team.Include(x => x.UserTeams).FirstOrDefaultAsync(x => x.Id == teamId);
    foreach (var userId in userIds)
    {
        var userTeam = existingTeam.UserTeams.FirstOrDefault(x => x.UserId == userId);
        if(userTeam != null)
        {
            existingTeam.UserTeams.Remove(userTeam);
        }
    }

    await dbContext.SaveAsync();
}

按 Id 删除

public async Task RemoveUsersFromTeam(int teamId, List<long> userIds)
{
    Team existingTeam = await dbContext.Team.FirstOrDefaultAsync(x => x.Id == teamId);
    foreach (var userId in userIds)
    {
        var userTeam = new UserTeam { UserId = userId });
        dbContext.UserTeams.Attach(userTeam);
        existingTeam.UserTeams.Remove(userTeam);
    }

    await dbContext.SaveAsync();
}

选项二不需要从数据库中 selecting UserTeams,并且在这方面会稍微更有效率。但是选项一可能更容易理解。您应该选择最适合您的情况。

我个人更喜欢选项二,因为包含将 select 整个实体,并且在某些情况下可能会超出必要的范围。