2 回答
TA贡献1785条经验 获得超8个赞
每次同步数据库时实例化一个新的数据上下文可以修复它,因为更改跟踪器从“零”开始。在我看来这不是一个好的解决方案。
我宁愿说这是“正确”的解决方案。默认情况下,上下文元数据(又名Model
)按上下文类型缓存,数据库连接由连接池维护,并且仅在需要时才打开/关闭。所以重用上下文实例的唯一好处是避免创建多个DbSet
实例。
同时,跟踪器会保留大量“实体”实例,并防止它们在SaveChanges
调用后被垃圾回收,而无需任何需要。不算潜在的多线程访问问题。
所以恕我直言,这就是要走的路——实例化新的上下文,用它做一些事情并处理它。
如果 EnsureDeleted 也“重置”更改跟踪器或者您可以手动执行,那就太好了。
确实那会很棒。但目前EnsureDeleted
EF Core 和 EF Core 都没有提供手动执行此操作的公共方式。
虽然有一种内部方法,但通常存在在未来某个 EF Core 版本中可能会更改的风险。添加
using Microsoft.EntityFrameworkCore.Infrastructure;
会允许你使用这样的东西
_context.ChangeTracker.GetInfrastructure().ResetState();
大概之前_context.Database.EnsureDeleted();
。这基本上证明你真的应该使用第一个选项(新上下文)。
更新(EF Core 3.0): ChangeTracker
甚至在内部也不再公开StateManager
,所以我们需要
using Microsoft.EntityFrameworkCore.Internal;
分别
_context.GetDependencies().StateManager.ResetState();
更新(EF Core 5.0):感谢评论中的Vaclav Elias,现在 ChangeTracker 公开了一个 Clear() 方法来清除所有被跟踪实体的 DbContext。
_context.ChangeTracker.Clear();
TA贡献1829条经验 获得超4个赞
以下几行对我有用。参考:https ://github.com/dotnet/efcore/issues/6282
context.ChangeTracker
.Entries()
.ToList()
.ForEach(e => e.State = EntityState.Detached);
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
- 2 回答
- 0 关注
- 71 浏览
添加回答
举报