我在实现 IEditable
的对象的 EndEdit
函数上有以下代码:
public void EndEdit()
{
using (var db = new Context())
{
if (Id == Guid.Empty)
{
db.Add(this);
db.SaveChanges();
}
else
{
var worklog = db.Find<Worklog>(Id);
worklog.Comment = Comment;
worklog.JiraIssue = JiraIssue;
worklog.Ticks = Ticks;
worklog.StartDate = StartDate;
db.SaveChanges();
}
}
}
对对象执行编辑后,db.Entry
在上下文中显示一个实体,状态为已修改,这正是我所期望的。但是,当我在执行 else block 后调用 db.SaveChanges
时,我收到以下错误消息:
The instance of entity type 'Worklog' cannot be tracked because another instance with the key value '{Id: b8476f6e-aab6-408f-ab75-f4944b9a0262}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
这是否与我试图将 IEditable
对象直接保存到数据库中这一事实有关?
super 困惑,欢迎任何帮助!
堆栈跟踪:
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Nullable`1 forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node, Boolean force)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode node, TState state, Func`3 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode node, TState state, Func`3 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState entityState, Boolean forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.NavigationReferenceChanged(InternalEntityEntry entry, INavigation navigation, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.NavigationReferenceChanged(InternalEntityEntry entry, INavigation navigation, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectNavigationChange(InternalEntityEntry entry, INavigation navigation)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges(IStateManager stateManager)
at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges()
at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges()
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at TimeTracker.ViewModels.WorklogViewModel.EndEdit() in C:\TimeTracker\ViewModels\WorklogViewModel.cs:line 120
实体类:
public class Worklog: IGuidEntity
{
public Guid Id { get; set; }
public DateTime StartDate { get; set; } = DateTime.Now;
public string Comment { get; set; }
public long Ticks { get; set; }
public bool Completed { get; set; }
public bool Published { get; set; }
public virtual JiraIssue JiraIssue { get; set; }
public virtual ICollection<TimeTrackerWorklog> OriginalWorklogs { get; set; }
public virtual TimeTrackerWorklog UserModifiedWorklog { get; set; }
}
View 模型:
public class WorklogViewModel : Worklog, IEditableObject
{
public void BeginEdit()
{
return;
}
public void EndEdit()
{
using (var db = new TimeTrackerContext())
{
if (Id == Guid.Empty)
{
db.Add(this);
db.SaveChanges();
}
else
{
var worklog = db.Find<TimeTrackerWorklog>(Id);
worklog.Comment = Comment;
worklog.JiraIssue = JiraIssue;
worklog.Ticks = Ticks;
worklog.StartDate = StartDate;
db.SaveChanges();
}
}
}
public void CancelEdit()
{
return;
}
}
最佳答案
也许发布有点晚了但是......我建议将代码从模型中分离到数据库访问,在你的情况下要更新的对象是类本身的一个实例。我要做的是创建一个名为 WorkLogDAL 的类并复制和更改方法 EndEdit(WorkLog workLog) 然后 else 方法将类似于:
else
{
db.TimeTrackerWorklog.Attach(workLog);
db.Entry(workLog).State = EntityState.Modified;
db.SaveChanges();
}
关于c# - 仅执行 db.SaveChanges() 时如何修复 "The instance of entity type XXX cannot be tracked",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53481302/