简体   繁体   English

EF Core删除多对多关系数据

[英]EF Core delete data in many to many relationship

I have the following tables: 我有以下表格:

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

the many to many relationship is defined in context: 多对多关系是在上下文中定义的:

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

I am trying to delete some users from a team with the following code: 我正在尝试使用以下代码从小组中删除一些用户:

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

but this query is not deleting the users that I pass. 但是此查询不会删除我通过的用户。 Anyone knows why this happens? 有人知道为什么会这样吗?

You can delete objects by Id using the new and attach method, or by passing the actual entity. 您可以使用new和attach方法通过ID或通过传递实际实体来删除对象。

Passing Entity 传递实体

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

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

Option two does not require selecting UserTeams from the database and will be slightly more efficient in that respect. 选项2不需要从数据库中选择UserTeam,在这方面效率会更高。 However option one may be more understandable. 但是,选项一可能更容易理解。 You should choose which best fits your situation. 您应该选择最适合您的情况。

Personally I prefer option two, as include will select the whole entity and in some cases that could be a lot more than necessary. 我个人更喜欢第二种方法,因为include将选择整个实体,在某些情况下可能会超出必要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM