EF Core一对多添加新对象

EF Core One to Many adding new object

我已经尝试了很多方法,但对于每种解决方案,我仍然会遇到不同类型的错误。我试图停止跟踪,尝试添加 challenge 本身,更新 competition 但所有这些似乎都不起作用。

我基本上有 1 个竞争到许多挑战,在这种情况下,1 个 competition 和 1 个 challenge 已经存在,我正在添加另一个 challenge,它有一个外国用 competition 键链接。我知道我之前曾问过类似的 ,但那是针对多个类别批量创建 1 个竞赛。我认为这更像是一个更新操作,似乎不起作用。非常感谢您的帮助! :)

InvalidOperationException: The instance of entity type 'Challenge' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Competition 型号 Class:

public class Competition
{
    [Key]
    public int ID { get; set; }

    public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
    public ICollection<Challenge> Challenges { get; set; }
}

Challenge 型号 Class:

public class Challenge
{
    [Key]
    public int ID { get; set; }

    [ForeignKey("CompetitionID")]
    public int CompetitionID { get; set; }
    [Display(Name = "Competition Category")]
    [ForeignKey("CompetitionCategoryID")]
    public int CompetitionCategoryID { get; set; }
}

控制器:

public async Task<IActionResult> Create([Bind("ID,XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
{
    var competition = await _context.Competitions
    .Include(c => c.CompetitionCategories)
    .Include(c1 => c1.Challenges)
    .AsNoTracking()
    .FirstOrDefaultAsync(m => m.ID == challenge.CompetitionID);

    if (ModelState.IsValid)
    {
        //_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        competition.Challenges.Add(challenge);

        _context.Update(competition);
        _context.Entry(competition).State = EntityState.Detached;
        _context.Entry(competition.Challenges).State = EntityState.Detached;
        await _context.SaveChangesAsync();
        //_context.Add(challenge);
        //await _context.SaveChangesAsync();
        //return RedirectToAction(nameof(Index));
        return RedirectToAction("Index", "Challenges", new { id = challenge.CompetitionID });
    }

     return View();
 }

更新:我实际上尝试只添加 challenge 本身,但它也引发了另一个错误。真是不知所措。

SqlException: Cannot insert explicit value for identity column in table 'Challenges' when IDENTITY_INSERT is set to OFF. System.Data.SqlClient.SqlCommand+<>c.b__122_0(Task result)

DbUpdateException: An error occurred while updating the entries. See the inner exception for details. Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)

更新 2:从绑定中删除 ID 有效,因为有一些未知的 ID 值被传入并被跟踪。 Ivan 关于使用外键添加新对象的回答是正确的。

public async Task<IActionResult> Create([Bind("XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
{
    //Codes here
    _context.Add(challenge);
    await _context.SaveChangesAsync();
}

处理断开连接的实体并不容易,需要不同的技术,具体取决于实体模型中导航/反向导航和 FK 属性的 presense/absense。

您的 Challenge class 具有明确的 FK 属性但没有导航属性。像这样添加新对象是最简单的操作 - 只需调用 DbContext.AddDbSet.Add:

_context.Add(challenge);
await _context.SaveChangesAsync();

但是,您遇到的异常让我认为 Create 方法接收到的 Challenge 对象的 PK 属性 Id 填充了一个值现有 Challenge。如果您真的想添加新的 Challenge 并且 Id 是自动生成的,请从绑定中排除 Id 或确保在调用 [ 之前将其设置为 0(零) =22=]。

有关详细信息,请参阅 Disconnected Entities 和 EF Core 文档中的相关链接。