我尝试了很多方法,但是每种解决方案仍然遇到不同类型的错误。我试图停止跟踪,尝试自己添加challenge
,更新competition
,但它们似乎都无法正常工作。
我基本上要面对许多挑战的比赛,在这种情况下,已经存在1 competition
和1 challenge
,并且我要添加另外一个具有外键链接的challenge
competition
。我知道我之前曾问过类似的question,但这是为了批量创建1个比赛到多个类别。我认为这更像是更新操作,似乎没有用。非常感谢您的帮助! :)
InvalidOperationException:实体类型“挑战”的实例 无法跟踪,因为另一个实例具有相同的键值 {'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();
}
更新:我实际上已经尝试仅添加challenge
本身,但是它还会引发另一个错误。真的很迷茫。
SqlException:无法为身份列插入显式值 IDENTITY_INSERT设置为OFF时,表“挑战”。 System.Data.SqlClient.SqlCommand + <> c.b__122_0(任务 结果)
DbUpdateException:更新条目时发生错误。看到 内部异常的详细信息。 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection 连接,CancelationToken cancelToken)
更新2:将ID从绑定中删除是可行的,因为传入了一些未知的ID值并对其进行了跟踪。 Ivan关于使用外键添加新对象的答案是正确的。
public async Task<IActionResult> Create([Bind("XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
{
//Codes here
_context.Add(challenge);
await _context.SaveChangesAsync();
}
答案 0 :(得分:2)
使用断开连接的实体并不容易,并且需要不同的技术,具体取决于实体模型中导航的存在与否/反向导航以及FK属性。
您的Challenge
类具有显式的FK属性,而没有导航属性。像这样添加新对象是最简单的操作-只需调用DbContext.Add
或DbSet.Add
:
_context.Add(challenge);
await _context.SaveChangesAsync();
但是,您遇到的异常使我认为Challenge
方法接收的Create
对象具有PK属性Id
,该属性填充了现有{{1} }。如果您确实要添加新的Challenge
并且Challenge
是自动生成的,请从绑定中排除Id
或确保在调用{之前将其设置为Id
(零)。 {1}}。
有关更多信息,请参阅EF Core文档中的Disconnected Entities和相关链接。