【问题标题】:EF error: The instance of entity type 'Object' cannot be tracked because another instanceEF 错误:无法跟踪实体类型“对象”的实例,因为另一个实例
【发布时间】:2021-01-31 21:03:25
【问题描述】:

我对这个和 Blazor 的新手感到迷茫并尝试学习它 (.NET 5)

我有一个简单的模型:

public class Status
{
    [Key]
    public int Id { get; set; }
    
    [Required]
    public string Name { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime LastUpdatedOn { get; set; }
}

Startup.cs,我注册了我的数据库和服务。

 services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("Default")),(ServiceLifetime.Scoped));

 services.AddAutoMapper(typeof(Startup));
 services.AddScoped<IStatusRepo, StatusRepo>();
 services.AddScoped<IStatusService, StatusService>();

我的组件的代码隐藏文件如下。 GetStatus 调用返回的 dto 与更新状态服务方法接受的不同,因此我将其转换为 UpdateStatus 方法。

public partial class EditStatus : ComponentBase
{
        [Parameter]
        public int StatusId { get; set; }

        [Inject]
        IStatusService StatusService { get; set; }

        [Inject]
        NavigationManager navigationManager { get; set; }

        public bool ShowLoadError { get; set; } = false;
        private StatusDetailDto StatusToEdit { get; set; } = new StatusDetailDto();

        protected override async Task OnInitializedAsync()
        {
            await GetStatusToEdit(StatusId);
        }

        public async Task GetStatusToEdit(int statusId)
        {
            try
            {
                StatusToEdit = await StatusService.GetStatusById(statusId);
            }
            catch (Exception ex)
            {
                ShowLoadError = true;
            }
        }

        protected async void UpdateStatus()
        {
            UpdateStatusDto updatedStatus = new UpdateStatusDto();
            updatedStatus.Id = StatusToEdit.Id;
            updatedStatus.Name = StatusToEdit.Name;

            StatusDetailDto statusUpdated = await StatusService.UpdateStatus(updatedStatus);

            if (statusUpdated != null)
            {
                navigationManager.NavigateTo("status/manage");
            }
            else
            {
                Console.WriteLine("No here");
            }
        }
    }

服务层是:

public async Task<StatusDetailDto> UpdateStatus(UpdateStatusDto statusDto)
{
    Status statusToUpdate = mapper.Map<UpdateStatusDto, Status>(statusDto);
    Status updatedStatus = await statusRepo.UpdateStatus(statusToUpdate);
    return mapper.Map<Status, StatusDetailDto>(updatedStatus);
}

还有回购

public async Task<Status> UpdateStatus(Status Status)
{
   if (Status is null) 
        throw new ArgumentNullException("Nulls are not allowed.");

   try
   {
        Status.LastUpdatedOn = DateTime.Now;

        // THIS LINE THROWS THE ERROR!
        _dbContext.Entry(Status).State = EntityState.Modified; 

        await _dbContext.SaveChangesAsync();
        return Status;
    }
    catch (Exception)
    {
        throw;
    }
}

也许我的服务生命周期有误?我也为我的dbcontext 尝试过短暂的生命周期。什么会引发此错误?

无法跟踪实体类型“Status”的实例,因为已经在跟踪具有相同键值 {'Id'} 的另一个实例。

【问题讨论】:

    标签: c# asp.net-core .net-core entity-framework-core blazor-server-side


    【解决方案1】:

    首先通过从 AddDBContext 中删除 ServiceLifetime.Scoped 来修复启动文件

    services.AddDbContext<ApplicationDbContext>(options =>
                        options.UseSqlServer(Configuration.GetConnectionString("Default")));
    

    然后更改您的 UpdateStatus 的代码

    public async Task<Status> UpdateStatus(Status status)
    {
       if (status is null) throw new ArgumentNullException("Nulls are not allowed.");
       try
       {
        var existedItem=_dbContext.Set<Status>().FirstOrDefaultAsync(i=i.Id==status.id);
           if(existedItem==null) throw new ArgumentNullException("Item is not found.");
          existedItem.LastUpdatedOn = DateTime.Now;
          _dbContext.Entry(existedItem).State = EntityState.Modified; 
          await _dbContext.SaveChangesAsync();
          return Status;
        }
        catch (Exception)
        {
          throw;
        }
    }
    

    【讨论】:

    • 当我已经在 args 中拥有该项目时,为什么我需要再次获取它?
    • 对不起,它不起作用。它仍然会抛出异常并跳过 saveChanges 调用。
    • 但是你的评论让我以类似的方式修复它,所以谢谢!
    • 可能是别的东西。我稍微修改了你的代码,它运行良好。我不是故意粗鲁,感谢您的回复。
    猜你喜欢
    • 2021-04-29
    • 2023-01-03
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    相关资源
    最近更新 更多