我有一个由两个相关表组成的视图ObjectDisplay
:Object
和State
。 State
表示Object
的状态,该视图会从最新的State
中为每个Object
提取一些详细信息。
在显示此信息的页面上,用户可以输入一些注释,从而创建新的State
。创建新的State
后,我立即从Object
中提取ObjectDisplay
并将其发送回局部视图并替换页面上网格中的Object
// Add new State.
db.States.Add(new State()
{
ObjectId = objectId,
Comments = comments,
UserName = username
});
// Save the changes (executes all of the above).
db.SaveChanges();
// Return the new Object information.
return db.Objects.Single(c => c.ObjectId == objectId);
根据我的数据库跟踪,Single
调用发生在SaveChanges
调用后大约70毫秒,并且它发生在同一个SPID上。
现在出现问题:数据库默认我看到返回的RecordDate
中State
的值为GETUTCDATE()
- 我自己没有提供日期。我看到的是Object
返回的State
RecordDate
State
旧版Comments
和新版State
State
}旧信息Object
。State
包含旧的{{1}}信息。当我刷新页面时,所有正确的信息都存在,但是在数据库/ EF的初始调用中返回了错误的信息。
那么......可能出错了什么?视图的更新速度不够快吗? EF会发生什么事吗?我真的不知道从哪里开始寻找。
答案 0 :(得分:1)
如果您之前在同一Object
中加载了相同的DbContext
实体,则EF将返回带有过时值的缓存实例,并忽略从SQL返回的值。
最简单的解决方案是在返回实体之前重新加载实体:
var result = db.Objects.Single(c => c.ObjectId == objectId);
db.Entry(result).Reload();
return result;
答案 1 :(得分:0)
这确实很奇怪。在SQL Server中,默认情况下不会保留视图,因此会立即显示基础数据中的更改。您可以在视图上创建聚簇索引并有效地保留查询,但在这种情况下,数据会同步更新,因此您应该立即看到更改。
如果您正在使用快照隔离级别,您的更改可能不会立即对其他SPID可见,但由于您使用相同的SPID并且不使用快照隔离,因此这也不是罪魁祸首。
此时唯一剩下的就是应用层。你实际上是在调用堆栈中使用单个调用的结果还是在某个地方丢失了。我假设刷新页面使用不同的代码路径,这可以解释为什么它在那里工作。