在Entity Framework中连续删除和添加实体时出现异常

时间:2018-05-06 08:45:57

标签: c# entity-framework

我正在尝试使用Entity Framework更新1-N关系。

我有两张桌子:

[HttpPost]
[Route("ad/story-location/attach")]
public async Task<HttpResponseMessage>Reattach([FromQuery]long storyid,[FromBody]StoryLocation[] data)
{
            try
            {
                var delRecords = from record in this._context.StoryLocation
                          where record.StoryId == data[0].StoryId
                          select record;
                this._context.RemoveRange(delRecords);
                await this._context.StoryLocation.AddRangeAsync(data);
                int rowsAffected = await this._context.SaveChangesAsync();

                return new HttpResponseMessage
                {
                    StatusCode = System.Net.HttpStatusCode.OK,
                    Content = new StringContent($"Rows affected:{rowsAffected.ToString()}")
                };
            }
            catch (Exception ex)
            {
                return new HttpResponseMessage
                {
                    StatusCode = System.Net.HttpStatusCode.NoContent,
                    Content = ex.ToHttpContent()
                };
            }
}

我想如果我想更有效地更新关系的N部分(对于给定的{{1}}),我会删除所有N个实体,然后我将“重新连接”它们。

所以我做了以下事情:

{{1}}

我得到以下例外:

  

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

1 个答案:

答案 0 :(得分:1)

    [HttpPost]
    [Route("ad/story-location/attach")]
    public async Task<HttpResponseMessage>Reattach([FromQuery]long storyid,[FromBody]StoryLocation[] data)
    {
        try
        {
            var delRecords = from record in this._context.StoryLocation
                      where record.StoryId == data[0].StoryId
                      select record;
            this._context.RemoveRange(delRecords);
            foreach(var item in delRecords)
            {
                 if (!item .IsNull()) // I'm using a extension method
                 {
                     // detach
                     _context.Entry(item ).State = EntityState.Detached;
                 }
            }
            await this._context.StoryLocation.AddRangeAsync(data);
            int rowsAffected=await this._context.SaveChangesAsync();
            return new HttpResponseMessage
            {
                StatusCode = System.Net.HttpStatusCode.OK,
                Content = new StringContent($"Rows affected:{rowsAffected.ToString()}")
            };
        }
        catch (Exception ex)
        {

            return new HttpResponseMessage
            {
                StatusCode = System.Net.HttpStatusCode.NoContent,
                Content = ex.ToHttpContent()
            };
        }
    }