我正在尝试使用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'来查看冲突的键值。
答案 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()
};
}
}