代码之家  ›  专栏  ›  技术社区  ›  zzdhxu

EF核心一对多添加新对象

  •  2
  • zzdhxu  · 技术社区  · 6 年前

    我尝试过很多方法,但对于每个解决方案,我仍然会遇到不同类型的错误。我尝试停止跟踪,尝试添加 challenge 自身,更新 competition 但它们似乎都不起作用。

    我基本上有1个竞争对手来应对许多挑战,在这种情况下,1 竞争 和1 挑战 已经存在,我正在添加另一个 挑战 它有一个与 竞争 . 我知道我问过类似的 question 以前,但那是为了批量创建一个竞争多个类别。我认为这更像是一个更新操作,似乎不起作用。非常感谢你的帮助!:)

    InvalidOperationException:实体类型“challenge”的实例 无法跟踪,因为具有相同键值的另一个实例 'id'已被跟踪。附加现有实体时, 确保只有一个具有给定键值的实体实例是 附属的。考虑使用 “dbContextOptionsBuilder.EnableSensitiveDataLogging”查看 键值冲突。

    Competition 模型类:

    public class Competition
    {
        [Key]
        public int ID { get; set; }
    
        public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
        public ICollection<Challenge> Challenges { get; set; }
    }
    

    Challenge 模型类:

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

    更新:我已经尝试添加 挑战 但它也抛出了另一个错误。真是不知所措。

    SQLException:无法为中的标识列插入显式值 表'challenges'当identity_insert设置为off时。 system.data.sqlclient.sqlcommand+<>c.b_uu122_0(任务 结果)

    DBUpdateException:更新条目时出错。见 详细信息的内部异常。 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(iRelationalConnection) 连接,取消令牌取消令牌)

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

    public async Task<IActionResult> Create([Bind("XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
    {
        //Codes here
        _context.Add(challenge);
        await _context.SaveChangesAsync();
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Ivan Stoev    6 年前

    使用断开连接的实体并不容易,并且需要不同的技术,这取决于实体模型中导航/innverse导航的存在/缺失以及FK属性。

    你的 Challenge 类具有显式FK属性,没有导航属性。添加这样的新对象是最简单的操作-只需调用 DbContext.Add DbSet.Add :

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

    但是,你得到的例外让我认为 挑战 对象接收者 Create 方法具有pk属性 Id 填充现有值 挑战 . 如果你真的想增加新的 挑战 身份证件 是自动生成的,排除 身份证件 从绑定或确保将其设置为 0 (零)呼叫前 Add .

    有关详细信息,请参阅 Disconnected Entities 以及EF核心文档中的相关链接。

    推荐文章