当前位置: 首页 > 知识库问答 >
问题:

EF多对多关系更新抛出重复键

纪晨
2023-03-14

我正在使用.NET5,并使用EF Core和MSSQL作为数据库。

我有两个类,他们之间有很多对很多的关系。这些都是从模型迁移到数据库的。DB表示例

迁移:

migrationBuilder.CreateTable(
            name: "TournamentUser",
            columns: table => new
            {
                TournamentsId = table.Column<int>(type: "int", nullable: false),
                UsersId = table.Column<int>(type: "int", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_TournamentUser", x => new { x.TournamentsId, x.UsersId });
                table.ForeignKey(
                    name: "FK_TournamentUser_Tournaments_TournamentsId",
                    column: x => x.TournamentsId,
                    principalTable: "Tournaments",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_TournamentUser_Users_UsersId",
                    column: x => x.UsersId,
                    principalTable: "Users",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

型号:

public class Tournament
{
    [Key]
    public int Id { get; set; }
    [Required, MaxLength(20)]
    public string Name { get; set; }
    [Required]
    public int MaxPlayers { get; set; }
    public int PlayersCount { get; set; }
    [Required]
    public DateTime Start { get; set; }
    public bool IsStarted { get; set; }
    public bool IsEnded { get; set; }
    public List<User> Users { get; set; }
}

public class User
{
    [Key]
    public int Id { get; set; }
    [Required, MaxLength(15)]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
    [Required, MaxLength(20)]
    public string Name { get; set; }
    [Required, MaxLength(20)]
    public string Surname { get; set; }
    [JsonIgnore]
    public List<Tournament> Tournaments { get; set; }
}

所以当我试图更新比赛模型

[HttpPut]
    public async Task<ActionResult<Tournament>> Put([FromBody] Tournament tournament)
    {
        _context.Tournaments.Update(tournament);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetTournament), new { id = tournament.Id }, tournament);
    }

我得到这个错误

Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_TournamentUser'. Cannot insert duplicate key in object 'dbo.TournamentUser'. The duplicate key value is (1, 1).

对此有什么可能的解决办法?我想保持我的多对多表UDPAT,因为每次更新锦标赛时,锦标赛的用户都可以被删除或添加。

可更新的锦标赛对象示例

共有1个答案

盖雪峰
2023-03-14

如果要更新tournment,请尝试从torment对象中删除用户。

 public async Task<ActionResult<Tournament>> Put([FromBody] Tournament tournament)
    {
         tournament.Users=null;
        _context.Tournaments.Update(tournament);
        await _context.SaveChangesAsync();
.....
   
    }

或者如果您想将用户添加到您的锦标赛中

var existing= _context
              .Tournaments
              .Include(u=>u.Users)
              .FirstOrDefault(t=> t.Id== tournament.Id);

if(existing==null) return ...error

if( existing.Users==null) existing.User=new List<User>();

if( existing.Users.Any(u=>u.Id=tournment.User.Id) return ...error

existing.Users.Add(tournment.User);
_context.Entry(existing).State = EntityState.Modified;
_context.SaveChanges();

它看起来很简单,但您为不显式添加多对多关系表而付出了代价。如果使用UserTournment表代码将更短。

你可以试试这个。我从没试过。如果有用,请告诉我:

var existing = _context
              .Tournaments
              .Include(u=>u.Users)
              .FirstOrDefault(t=> t.Id== tournament.Id);

if(existing==null) return ...error

_context.Entry(existing).CurrentValues.SetValues(tournment);

_context.SaveChanges();
 类似资料:
  • 问题内容: 伙计们,我正在努力为我的公司制作一个简单的票证生成系统,以吸引人。目前,我的MSSQL数据库中有一个名为的表,另一个名为的表。 我的应用程序是C#Windows窗体,因此在新的票证生成窗体上,我有许多文本框和一个用于分配工程师的comboBox,由填充。生成票证后,以这种形式输入的所有信息都将与from一起存储。 效果很好,但是后来我的客户要求我添加选项,以便可以在一张票上分配3名工程

  • 问题内容: 我目前正在使用ActiveAndroid,并且在过去的几个小时里一直在尝试建立多对多关系,但是我还是无法正常工作。我希望你能帮助我: 我有“学生”和“课程”的模型,一个学生可以有很多课程,而一个课程有很多学生。基本上,这就是我在“ StudentCourse”模型中所拥有的: 现在,我要做的是使用以下代码获取“课程X中的所有学生”: 但是我收到以下错误: java.lang.Class

  • 在本章中,让我们了解和学习多对多的关系。要表示多对多关系,必须创建第三个表(通常称为联接表),将多对多关系分解为两个一对多关系。 为此,我们还需要添加一个联接表。 下面先添加一个表。表的定义如下所示 - 现在创建一个多对多的关系。假设有多个作者在多个项目上工作,反之亦然。 如您所知,我们在中有一个字段,所以为它创建了一个表。但现在不再需要这个字段了。 选择字段,然后按下删除 按钮,将看到以下消息。

  • 我还想知道如何定义每个模型上的关系--你是否需要或者是否可以只在用户上定义关系?

  • 我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁:

  • 我正在php上研究多对多关系,我有3个表,包括电影名称和电影id的movie表genre表包括类型和类型id的movie_genre表包括电影id和类型id的movie_genre表 genre表有这些值 我使用下面的代码来获取数据 但结果将类似于 movie_id movie_name genre[1] movie_id movie_name genre[2] movie_id movie_na