我正在尝试更新一个实体
Tender
,这个实体有一个TenderOffer
列表,而这个TenderOffer
又有一个Company
实体。当我试图更新Tender时,我遇到了以下错误。
Message=The instance of entity type 'Company' cannot be tracked because another instance with the key value '{ID: 4}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
Source=Microsoft.EntityFrameworkCore StackTrace: at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntryentry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKeykey, InternalEntityEntry entry, Boolean updateDuplicate) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKeykey, InternalEntityEntry entry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntryentry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntryentry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityStateoldState, EntityState newState, Boolean acceptChanges, BooleanmodifyProperties) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityStateentityState, Boolean acceptChanges, Boolean modifyProperties,Nullable`1 forceStateWhenUnknownKey) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1node) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1node, Func`2 handleNode) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1node, Func`2 handleNode) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1node, Func`2 handleNode) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1node, Func`2 handleNode) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntryrootEntry, EntityState targetState, EntityStatestoreGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.SetEntityState(InternalEntityEntryentry, EntityState entityState) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Update(TEntity entity) at DAL.Repositories.TendersRepository.<UpdateTender>d__10.MoveNext() in C:\Progetti\DAL\Repositories\TendersRepository.cs:line 613 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at UI.Controllers.TenderController.<SelectTenderWinner>d__13.MoveNext() in C:\Progetti\UI\Controllers\TenderController.cs:line 808 This exception was originally thrown at this call stack: [External Code] DAL.Repositories.TendersRepository.UpdateTender(ML.Models.Tender) in TendersRepository.cs [External Code] UI.Controllers.TenderController.SelectTenderWinner(int,int, bool) in TenderController.cs
我不明白为什么会出现这个追踪错误。我已经禁用了DBContext构造函数中的所有追踪行为。
base.ChangeTracker.AutoDetectChangesEnabled = false;
base.ChangeTracker.LazyLoadingEnabled = false;
base.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
我在所有的查询中都使用了AsNoTracking()。我无法理解为什么EF Core还是在进行跟踪。
entity_one是"Tender",entity_two是"TenderOffer"
以下是控制器中的代码:
try
{
//id and winnerOfferID are parameters of the request
Tender tender = await this._tenderRepository.GetTender(id, false, this.CurrentCompanyID);
TenderOffer offer = tender.TenderOffers.FirstOrDefault(o => o.ID == winnerOfferID)
tender.IsClosed = true;
tender.ClosureDate = DateTime.UtcNow;
tender.ShowWinner = showWinner;
tender.WinnerOfferID = winnerOfferID;
tender.TenderOffers.ForEach(o =>
{
if (o.ID == winnerOfferID)
{
o.Status = TenderOfferStatus.Winner;
}
else
{
o.Status = TenderOfferStatus.Rejected;
o.Company = null;
}
});
await this._tenderRepository.UpdateTender(tender);
return Ok();
}
catch (Exception ex)
{
return StatusCode(500);
}
这是更新函数:
public async Task<Tender> UpdateTender(Tender tender)
{
if (tender == null || tender.ID <= 0)
throw new ArgumentNullException("Cannot update, tender is null");
this._context.Tenders.Update(tender);
await this.SaveChangesAsync();
return tender;
}
这是 Get 函数:
public async Task<Tender> GetTender(int id, bool skipCompanyCheck = false, int? companyId = null)
{
IQueryable<Tender> query = this._context.Tenders.AsNoTracking()
.Include(t => t.Company).AsNoTracking()
.Include(t => t.Company).ThenInclude(c => c.Logo).AsNoTracking();
//Other include based on parameters, ALSO TENDER OFFERS
tender = await query.Where(tender => tender.ID == id).FirstOrDefaultAsync();
return tender;
}
this._context.Tenders.Update(tender);
不需要被调用吗?阅读该方法的常见摘要。 - Seabizkit