【问题标题】:Update is not working for many-to-many relationship. Entity Framework Core 2.2更新不适用于多对多关系。实体框架核心 2.2
【发布时间】:2020-05-15 05:14:55
【问题描述】:

我在游戏和类别之间存在多对多的关系。我正在使用 Sql Server。一个游戏可以有多个类别。创建操作有效,但更新无效。收到错误:

InnerException:违反主键约束“PK_GameCategories”。无法在对象“dbo.GameCategories”中插入重复键。重复键值为 (1003, 1)。\r\n语句已终止。

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

    [Display(Name = "Game Name")]
    public string Name { get; set; }

    [Display(Name = "Game Categories")]
    public ICollection<GameCategory> GameCategories { get; set; }
}

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

    [Display(Name = "Game Category")]
    public string Name { get; set; }

    [Display(Name = "Game Categories")]
    public ICollection<GameCategory> GameCategories { get; set; }
}

public class GameCategory
{
    public int GameId { get; set; }
    public Game Game { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

// --------------------------
GameController/Edit Action [Working Perfectly]
// -------------------------
[HttpGet]
[Route("edit-game/{id}")]
public async Task<IActionResult> EditGame(int id)
{
      try
      {
                if (id == null) return NotFound();
                var gameInDb = await _db.Games.FirstOrDefaultAsync(g => g.Id == id);
                if (gameInDb == null) return NotFound();

                var model = new GameChangeViewModel()
                {
                    Title = $"Edit {gameInDb.Name}",
                    Name = gameInDb.Name,
                    // Displaying list of categories
                    GameCategoryList = _db.Categories
                        .Select(c => new SelectListItem() { Text = c.Name, Value = c.Id.ToString()}).ToList(),
                    // loading selected values
                    GameCategoryId = _db.GameCategories.Where(c=>c.GameId == gameInDb.Id).Select(s=>s.CategoryId).ToList()
                };

                return View(model);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return NotFound();
            }
        }

以下代码不工作并引发上述异常。

[HttpPost]
        [Route("edit-game-post")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> EditGamePost(GameChangeViewModel model)
        {
            try
            {
                if (!ModelState.IsValid) return View(nameof(EditGame), model);

                var gameInDb = await _db.Games.FirstOrDefaultAsync(g => g.Id == model.Id);
                if (gameInDb == null)
                {
                    ModelState.AddModelError("", "No Data");
                    return View(nameof(EditGame), model);
                }

                _db.GameCategories.RemoveRange(gameInDb.GameCategories);
                _db.SaveChanges();

                gameInDb.Name = model.Name;
                var category = _db.Categories.Where(c => model.GameCategoryId.Contains(c.Id)).ToList();
                foreach (Category cat in category)
                {
                    gameInDb.GameCategories.Add(new GameCategory()
                    {
                        Category = cat, Game = gameInDb
                    });
                }

                await _db.SaveChangesAsync();
                return RedirectToAction(nameof(Index));

            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                ModelState.AddModelError("", "Exception Happen");
                return View(nameof(EditGame), model);
            }
        }


不幸的是,我还没有找到任何适合多对多关系的 CRUD 操作。谢谢

【问题讨论】:

  • 我们可以看看你的模型是什么样子的吗?可能是 SQL 或您正在使用的任何数据库。
  • 尝试调试代码,看看哪里出了问题,我看到你使用“parsedGuid”来获取gameInDb,但我不知道你从哪里得到这个值。
  • 谢谢。百合。我刚刚编辑了它。实际上原始代码很大。我只发布了一小段代码。
  • SQL Server 中的 GameCategory 表设计器是什么样的?以及如何在 GameCategory 表中创建新的列 ID 作为主键?
  • 谢谢@Asherguru。它确实解决了问题。如果您使用一些代码发布此评论作为答案,我将很乐意接受。非常感谢。

标签: c# entity-framework-core many-to-many insert-update ef-core-2.2


【解决方案1】:

尝试在 GameCategory 表中创建新的列 ID 作为主键。

【讨论】:

    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2021-02-15
    • 2021-10-02
    相关资源
    最近更新 更多