希望下面的代码片段足够清楚地解释问题。 _db
是DbContext
的实例。
// this scenario is only for learning purpose
Author a = _db.Authors.Find(1831);
int id = a.AuthorId;
a = null;
Author stub = new Author { AuthorId = id };
_db.Remove(stub);
_db.SaveChanges();
上面的代码产生
'无法跟踪实体类型'Author'的实例,因为已经跟踪了{'AuthorId'}具有相同键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'查看冲突的键值。'
如何释放a
使其不受跟踪?
答案 0 :(得分:2)
您可以尝试AsNoTracking()
。
_db.Authors.AsNoTracking()。Where(a => a.AuthorId == 1831).FirstOrDefault();
答案 1 :(得分:1)
查询a时,应使用AsNoTracking
选项。
例如下面的查询获取所有博客项目,但是如果您尝试删除它们,则不会出现任何错误。
var blogs = context.Blogs
.AsNoTracking()
.ToList();
您可以在查询中设置AsNoTracking
,也可以在上下文对象上对其进行设置,如下所示:
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var blogs = context.Blogs.ToList();
这应该可以帮助您解决此问题。
有关更多详细信息,请参见this MSDN page。
答案 2 :(得分:1)
有多种方法可以执行此操作,但是我发现这是最简单的,因为您正尝试分离特定的实体。
_db.Entry(a).State = EntityState.Detached
此外,它不需要更改任何其他代码,包括但是您获取了实体本身。
这一行非常清楚其意图。它还允许以下操作:
当我要做的只是分离某些东西时,我不喜欢在DbContext
上更改现有查询的想法。