这里记录一个在使用.net core中ef core执行数据库操作时遇到的问题:
我在代码中使用DbContext下的Update方法准备将更改后的数据像这样步到数据库:
_context.Menus.Update(menu);
这是很常见的用法,但没想到一直报如下错误:
The instance of entity type 'Menu' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.
使用谷歌翻译翻译为:
无法跟踪实体类型“Menus”的实例,因为已经跟踪了具有相同键值的{'Id'}的另一个实例。
我的代码如下:
if (!menu.OrderNumber.HasValue)
{
var maxOrderItem =
_context.Menus.Where(x => x.ParentId == menu.ParentId)
.OrderByDescending(x => x.OrderNumber)
.FirstOrDefault();
menu.OrderNumber = maxOrderItem != null ? maxOrderItem.OrderNumber + 1 : 999;
}
///EF core中没有AddOrUpdate方法,所以针对是新增菜单还是修改菜单做出判断
if (isNewMenu)
{
_context.Menus.Add(menu);
}
else
{
_context.Menus.Update(menu);///此处报出上述异常
}
_context.SaveChanges();
我通过百度,发现国内网站上没有出现类似错误的记载,最后,我在stackoverflow上看到一段类似问题描述:
该用户描述,他进行了如下尝试:
在使用_context获取值时,使用AsNoTracking()方法,我进行尝试,修改我的代码如下:
if (!menu.OrderNumber.HasValue)
{
var maxOrderItem =
_context.Menus.AsNoTracking().Where(x => x.ParentId == menu.ParentId)
.OrderByDescending(x => x.OrderNumber)
.FirstOrDefault();
menu.OrderNumber = maxOrderItem != null ? maxOrderItem.OrderNumber + 1 : 999;
}
///EF core中没有AddOrUpdate方法,所以针对是新增菜单还是修改菜单做出判断
if (isNewMenu)
{
_context.Menus.Add(menu);
}
else
{
_context.Menus.Update(menu);
}
_context.SaveChanges();
发现我遇到的这个问题得以圆满解决。
我在这里记录一下这个问题,但其中的道理我没有深究,就不说了。