简体   繁体   English

无法跟踪实体类型“x”的实例,因为已在跟踪另一个具有键值“{Id: 6}”的实例

[英]The instance of entity type 'x' cannot be tracked because another instance with the key value '{Id: 6}' is already being tracked

I am working a asp .netcore 6.0 clean architecture project.我正在做一个 asp .netcore 6.0 clean architecture 项目。

When I try to update a site, I got this error,当我尝试更新网站时,出现此错误,

System.InvalidOperationException: The instance of entity type 'SiteCode' cannot be tracked because another instance with the key value '{Id: 6}' is already being tracked. System.InvalidOperationException:无法跟踪实体类型“SiteCode”的实例,因为已在跟踪另一个具有键值“{Id: 6}”的实例。 When attaching existing entities, ensure that only one entity instance with a given key value is attached.附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

Before We use services, in there this same code worked fine.在我们使用服务之前,同样的代码在那里运行良好。 Now we move to clean architecture(CQRS and Mediatr).现在我们转向清洁架构(CQRS 和 Mediatr)。 I used same update code but I got this error.我使用了相同的更新代码,但我收到了这个错误。

.AsNoTracking() I tried with var result = await _DbContext.SiteCodes.FindAsync(request.Id).AsNoTracking(); .AsNoTracking()我尝试使用var result = await _DbContext.SiteCodes.FindAsync(request.Id).AsNoTracking(); this line,这条线,

But got error as,但得到错误,

'ValueTask<SiteCode?>' does not contain a definition for 'AsNoTracking' and no accessible extension method 'AsNoTracking' accepting a first argument of type 'ValueTask<SiteCode?>' could be found (are you missing a using directive or an assembly reference?) [Application]

Here is my codes这是我的代码

UpdateSiteCommandHandler.cs UpdateSiteCommandHandler.cs

public async Task<SiteCode> Handle(UpdateSiteCommand request, CancellationToken cancellationToken)
    {
        var result = _mapper.Map<SiteCode>(request);

        _DbContext.SiteCodes.Update(result);  // goes to exception after this line

        await _DbContext.SaveChangesAsync(cancellationToken);

        return result;
    }

GetSiteByIdQueryHandler.cs GetSiteByIdQueryHandler.cs

public async Task<SiteCode> Handle(GetSiteByIdQuery request, CancellationToken cancellationToken)
    {
        
        var result = await _DbContext.SiteCodes.FindAsync(request.Id);

        if (result == null)
        {
            throw new NotFoundException(nameof(SiteCode), request.Id);
        }

        return result;

    }

controller controller

public async Task<IActionResult> Update(int id, [FromBody] UpdateSiteCommand command)
        {
            command.Id = id;

            var siteCode = await _mediator.Send(new GetSiteByIdQuery(Id: id));

            var result = await _mediator.Send(command);
            
            return Ok(result);

        }

DependencyInjection.cs依赖注入.cs

public static class DependencyInjection
{
    public static IServiceCollection AddApplication(this IServiceCollection services)
    {
        services.AddAutoMapper(Assembly.GetExecutingAssembly());
        services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
        services.AddMediatR(Assembly.GetExecutingAssembly());
        services.AddTransient(typeof(IPipelineBehavior<,>), typeof(PerformanceBehaviour<,>));  // I tried with AddScoped() But not work
       
        return services;
    }

}

in DbContext在 DbContext 中

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            var entries = ChangeTracker
                .Entries()
                .Where(e => e.Entity is AuditableEntity && (
                        e.State == EntityState.Added
                        || e.State == EntityState.Modified));

            foreach (var entityEntry in entries)
            {
                if (entityEntry.State == EntityState.Added)
                {
                    ((AuditableEntity)entityEntry.Entity).CreatedAt = DateTime.UtcNow;
                    ((AuditableEntity)entityEntry.Entity).CreatedBy = _httpContextAccessor?.HttpContext?.User?.Identity?.Name ?? null;
                }
                else
                {
                    Entry((AuditableEntity)entityEntry.Entity).Property(p => p.CreatedAt).IsModified = false;
                    Entry((AuditableEntity)entityEntry.Entity).Property(p => p.CreatedBy).IsModified = false;
                }

                ((AuditableEntity)entityEntry.Entity).ModifiedAt = DateTime.UtcNow;
                ((AuditableEntity)entityEntry.Entity).ModifiedBy = _httpContextAccessor?.HttpContext?.User?.Identity?.Name ?? null;
            }

            var result = await base.SaveChangesAsync(cancellationToken)

         return result;
        }

Anyone has idea how can solve this issue?任何人都知道如何解决这个问题?

Try to add the method AsNoTracking() after SiteCodes to your query in Handler (GetSiteByIdQueryHandler.cs).尝试将 SiteCodes 之后的 AsNoTracking() 方法添加到 Handler (GetSiteByIdQueryHandler.cs) 中的查询。

public async Task<SiteCode> Handle(GetSiteByIdQuery request, CancellationToken cancellationToken)
{
    
    var result = await _DbContext.SiteCodes.AsNoTracking().FindAsync(request.Id);

    if (result == null)
    {
        throw new NotFoundException(nameof(SiteCode), request.Id);
    }

    return result;
}

EF Core uses ChangeTracker to detect changes in loaded entities, and better (not faster) solution is to load entity for update. EF Core 使用 ChangeTracker 来检测加载实体的变化,更好(不是更快)的解决方案是加载实体进行更新。

public async Task<SiteCode> Handle(UpdateSiteCommand request, CancellationToken cancellationToken)
{
    // the following code will load entitiy if it is still not loaded.
    var dbRequest = await _DbContext.SiteCodes.FindAsync(request.Id);

    if (dbRequest == null)
        throw new Exception("Not found");

    var result = _mapper.Map<SiteCode>(request, dbRequest);

    await _DbContext.SaveChangesAsync(cancellationToken);

    return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误:无法跟踪实体类型“X”的实例,因为已在跟踪另一个具有键值“{ID:3}”的实例 - Error: The instance of entity type 'X' cannot be tracked because another instance with the key value '{ID: 3}' is already being tracked 无法跟踪实体类型 X 的实例,因为已跟踪具有键值“{Id:}”的另一个实例 - The instance of entity type X cannot be tracked because another instance with the key value '{Id:}' is already being tracked “无法跟踪实体类型‘用户’的实例,因为已使用 UserManager 跟踪另一个具有键值‘{x}’的实例 - "The instance of entity type 'User' cannot be tracked because another instance with the key value '{x}' is already being tracked with UserManager 无法跟踪实体类型“Item”的实例,因为已跟踪另一个具有与 {'Id'} 相同键值的实例 - The instance of entity type 'Item' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“配置文件”的实例,因为已在跟踪另一个具有键值“{Id: 1087}”的实例 - The instance of entity type 'Profile' cannot be tracked because another instance with the key value '{Id: 1087}' is already being tracked 无法跟踪实体类型“书签”的实例,因为已经在跟踪具有相同键值 {'ID'} 的另一个实例 - The instance of entity type 'Bookmark' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked 实体类型的实例 <T> 无法跟踪,因为已经跟踪了另一个具有相同的{&#39;Id&#39;}键值的实例 - The instance of entity type <T> cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“ Customer”的实例,因为已经跟踪了另一个键值为“ {Id:…}”的实例 - The instance of entity type 'Customer' cannot be tracked because another instance with the key value '{Id: …}' is already being tracked 无法跟踪实体类型 Model 的实例,因为已跟踪另一个具有相同 {&#39;Id&#39;} 键值的实例 - The instance of entity type Model cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“Bus”的实例,因为已经在跟踪具有相同键值 {'Id'} 的另一个实例 - The instance of entity type ‘Bus’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM