无法跟踪实体类型Menu的实例

时间:2019-10-24 16:57:32

标签: c# asp.net-mvc entity-framework asp.net-core dependency-injection

我开始了一个新的asp.net核心项目。如您所知,Core 2.1版具有依赖项注入。

我有一个名为MenuModel的模型,可以在数据库中创建一个表。我为模型添加了一个名为IMenuRepository的接口,以及一个实现了我的接口的类MenuRepository。

我尝试像这样在我的存储库中编辑菜单

    public async Task Edit(Menu menu)
    {
        menu.UpdatedBy = _userId;
        menu.UpdatedDate = DateTime.Now;

        _db.Entry(menu).State = EntityState.Modified;
        await _db.SaveChangesAsync();
    }

我将这行代码添加到了startup.cs中以进行依赖注入

services.AddTransient<IMenuRepository, MenuRepository>();

我发现了另一个问相同问题的问题,回答说我必须更改我的startup.cs代码,例如:

services.AddScoped<IMenuRepository, MenuRepository>();

我做到了,我也尝试了其他方法,但是我总是遇到这个错误。我搜索了几次,但是找不到解决我问题的方法。

有一次我在编辑之前从我的DatabaseContext中分离了模型,并且遇到了同样的错误。

我尝试使用此代码进行更新,但没有结果

_db.Update(menu);

这是我的错误描述:

**处理请求时发生未处理的异常。

InvalidOperationException:无法跟踪实体类型“ Menu”的实例,因为已经跟踪了另一个具有相同“ {'MenuId'}”键值的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'来查看冲突的键值。 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.ThrowIdentityConflict(InternalEntityEntry entry)**

另一方面,我有一部分用于发布和取消发布菜单的代码,它们可以更改记录状态并像这样编辑菜单,并且效果很好。

    public async Task Publish(int id)
    {
        Menu menu = await Find(id);

        menu.UpdatedBy = _userId;
        menu.UpdatedDate = DateTime.Now;
        menu.Status = eStatus.Published;

        _db.Entry(menu).State = EntityState.Modified;
    }

区别仅在于我发送菜单ID来发布方法,而发送菜单obj来编辑。

1 个答案:

答案 0 :(得分:0)

用不同的语言搜索后,我找到了问题的答案

我将编辑方法更改为此:

    public async Task Edit(Menu menu)
    {
        menu.UpdatedBy = _userId;
        menu.UpdatedDate = DateTime.Now;

        var editVersion = await Find(menu.MenuId);
        if (editVersion != null)
        {
            _db.Entry(editVersion).CurrentValues.SetValues(menu);
        }
        await _db.SaveChangesAsync();
    }