ASP.NET API引发实体框架错误

时间:2018-05-23 17:59:32

标签: c# entity-framework asp.net-core dbcontext asp.net-core-webapi

以下是我的API代码,但它始终返回500内部服务器错误。执行SaveChangesAsync()时会抛出异常。

  

实体类型实例' NewsReport'无法跟踪,因为已经跟踪了具有{' Id'}的相同键值的另一个实例。附加现有实体时,请确保仅附加具有给定键值的一个实体实例。考虑使用' DbContextOptionsBuilder.EnableSensitiveDataLogging'查看冲突的键值

[HttpPut("{id}")]
public async Task<IActionResult> EditDevblog([FromBody] DevblogModel devblog, int id)
{
    if (!ModelState.IsValid)
        return BadRequest();

    var devblogInDb = _context.DevblogModels
        .Include(d => d.Fixs)
        .Include(d => d.News)
        .Include(d => d.Removes)
        .Include(d => d.Updates)
        .SingleOrDefault(d => d.Id == id);

    if (devblogInDb == null)
        return NotFound();

    devblogInDb.Fixs = devblog.Fixs;
    devblogInDb.News = devblog.News;
    devblogInDb.Removes = devblog.Removes;
    devblogInDb.Updates = devblog.Updates;
    devblogInDb.PatchName = devblog.PatchName;

    await _context.SaveChangesAsync();
    var h = _context.DevblogModels.SingleOrDefault(d => d.Id == id);
    return Ok();
}

1 个答案:

答案 0 :(得分:0)

请参阅我的回答here

当您使用新实例替换子实体实例时,EF Core会抛出此异常,就像您在此处所做的那样:

devblogInDb.Fixs = devblog.Fixs;
devblogInDb.News = devblog.News;
devblogInDb.Removes = devblog.Removes;
devblogInDb.Updates = devblog.Updates;
devblogInDb.PatchName = devblog.PatchName;

不幸的是,唯一可行的替代方法是直接更新当前的子实体属性。根据我的原始答案:

// In your DevblogModels and assuming a 1:1 relationship
public void SetNewsReport(NewsReport newsReport)
{   
    this.News.UpdateFrom(newsReport);
}

// Then, on your NewsReport entity
internal void UpdateFrom(NewsReport other)
{
    this.Title = other.Title;
    this.Article = other.Article;
    // other properties...
}

我原来的答案中的第二种方法建议分离实体,替换子实例,然后重新附加并尝试保存。在我使用这种方法的尝试中,异常消失了,但数据并没有持久存在于数据库中。也许你会比我更幸运...

context.Entry(devblogInDb).State = EntityState.Detached;
devblogInDb.Fixs = devblog.Fixs;
devblogInDb.News = devblog.News;
devblogInDb.Removes = devblog.Removes;
devblogInDb.Updates = devblog.Updates;
devblogInDb.PatchName = devblog.PatchName;
context.Entry(devblogInDb).State = EntityState.Modified;

进一步

正如我原来的答案所暗示的那样,EF Core一直是个问题。这个问题应该在EF Core 2.1中修复,但是,我原来答案的OP是使用EF Core 2.1的候选版本。显然这个问题要么没有削减,要么修复到位仍然有一些错误(毕竟它只是一个候选版本......)

关于这个主题的精彩阅读Julie Lerman在MSDN杂志上发表了一篇文章,你可以找到here。她还有一些您可以使用的替代解决方案。