【发布时间】:2013-08-23 10:38:56
【问题描述】:
我已经得到了非常奇怪的行为形式的实体框架。我正在编写一个 WebApi 应用程序,因此我从浏览器获取的对象是断开连接/分离的。我返回的数据是事务性的,因此它与数据库中的任何给定表都不匹配。我必须进行大量查找和数据操作才能对数据库进行实际更新。
我似乎遇到的问题是,在查询数据时,我正在填满 Tracked Changes 缓存。这对我来说似乎不是问题,因为真正的数据来源应该是数据库。当我最终更改数据并调用 SaveChanges 时,我得到约束错误。这是我的步骤。
- 查询数据。
- 创建要插入的行。
- 将行与 db 进行比较并进行 db 更改。
查看 Ctx.ChangeTracker.Entries() 中的数据后,我发现一个要删除的条目在应该删除时被标记为已修改。我解决它的方法是为第 3 步创建一个新的上下文。它神奇地开始工作。我以为就是这样,但在我的测试用例中,我最后一次读取数据库以验证我的事务是否正确写入。我得到了一个应该已经被删除的额外行。事实上,当直接检查数据库时。最后一次读取的新上下文再次解决了问题。
我只是假设默认缓存设置仅用于跟踪更改而不是加速查询。
如果我尝试在查询中使用 AsNoTracking,我也会遇到麻烦,因为如果我尝试删除这样查询的行,我会收到错误。在我的代码中,我不知道我是否要在以后删除或修改。有没有办法清除缓存,这样我就不需要创建新的上下文了?
有没有更好的方法来处理这些问题?
编辑:
AsNoTracking 在某种程度上可以解决问题。我仍然发现自己实例化了更多 DbContext 副本以防止错误。必须按顺序删除多对一实体,否则会触发空外键错误。
var details = oldInvoice.details.ToList();
Context.Entry(oldInvoice).State = EntityState.Unchanged;
Context.Entry(oldInvoice).State = EntityState.Deleted;
details.ForEach(a => Context.Entry(a).State = EntityState.Deleted);
【问题讨论】:
-
长时间保留上下文是个坏主意,因为当跟踪图包含大量实体时,它的性能不佳。我的建议是不要在请求之间重复使用您的上下文。这也应该可以解决任何并发更新问题
标签: c# entity-framework asp.net-web-api