视图是否会立即反映其基础表中的数据更改?

时间:2013-03-21 20:58:04

标签: sql-server-2008 entity-framework views

我有一个由两个相关表组成的视图ObjectDisplayObjectStateState表示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上。

现在出现问题:数据库默认RecordDateState的值为GETUTCDATE() - 我自己没有提供日期。我看到的是Object返回的State RecordDate State旧版Comments和新版State State }旧信息Object我看到返回的State包含旧的{{1}}信息。当我刷新页面时,所有正确的信息都存在,但是在数据库/ EF的初始调用中返回了错误的信息。

那么......可能出错了什么?视图的更新速度不够快吗? EF会发生什么事吗?我真的不知道从哪里开始寻找。

2 个答案:

答案 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并且不使用快照隔离,因此这也不是罪魁祸首。

此时唯一剩下的就是应用层。你实际上是在调用堆栈中使用单个调用的结果还是在某个地方丢失了。我假设刷新页面使用不同的代码路径,这可以解释为什么它在那里工作。