Entity Framework:如何检测数据库中的外部更改

23

我有一个存储过程,它会在数据库中改变很多数据。这个存储过程是从应用程序中调用的,该应用程序同时使用EF进行数据操作。

所以我点击一个按钮,存储过程在数据库中运行,数据被改变,但EF向用户显示的仍然是旧数据。

有没有办法强制DbContext或ObjectContext从数据库刷新数据?ObjectContext.Refresh()可能是解决方法,但我不想为每个可能被更改的表都调用此方法。我希望所有表都可以一次性刷新。

我正在使用Entity Framework 5,目标是.NET 4.0

编辑:补充说明,新增数据可用,但对现有数据进行的修改未反映在EF中。我可以看到新添加的记录,但无法看到我对现有记录所做的更改。


很抱歉,您不能这样做。也许这是好的,因为在其他情况下,刷新整个数据库将被选中到您的应用程序。 - Kirill Bestemyanov
我在想,因为DBContext总是直接从数据库中获取数据,即使您已经缓存了数据。您必须刷新数据而不是数据上下文,我的意思是重新加载来自DB的数据? - Bassam Alugili
@BassamAlugili,我已经澄清了问题,请查看编辑。 - Mert Akcakaya
1
使用SignalR绝对可以实现这一点。请查看Brij的博客文章:http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency - Marco
@Serv,看起来是个不错的工具,但我并不需要被通知有关更改的问题。我无法强制EF从数据库中加载更新的数据。它不会更新已更改的实体属性。 - Mert Akcakaya
在提到的博客文章中,用户更改数据后,更新后的数据会立即推送到所有客户端。这不是你想要的吗? - Marco
2个回答

17

你的DbContext应该是短暂存在的。创建它,运行查询并处理掉它。

using (var context = new MyProject.DbContext())
{
    // run your query here
}

不要保留上下文。这样,您就不会遇到旧数据的任何问题。


1
我正在为存储库使用相同的上下文,并且该上下文由IoC注册。 - Mert Akcakaya
1
@Mert,使用IoC库仍然可以拥有短暂的上下文。例如,使用Autofac和Web API,您可以执行builder.Register(c => context).As<IIntranetContext>().InstancePerApiRequest(); - user247702
问题在于,我需要重新初始化所有的repo,因为它们依赖于上下文。服务层与repo而非上下文进行交互。 - Mert Akcakaya
1
@IvanFerrerVilla 很抱歉没有及时回复,可能是我错过了通知。通常在检索实体后立即将其映射到业务对象或视图模型(或其他内容)。要进行更新,您可以再次检索实体并修改属性(更容易),或者手动附加仅设置了主键字段的实体,填充属性并将其标记为已更改(不执行select查询)。我已经有几年没有积极使用EF了,所以我对于今天的最佳实践不是很了解。 - user247702
1
@IvanFerrerVilla 请参考 https://dev59.com/3nPYa4cB1Zd3GeqPpv49#17442858,了解手动附加方法的示例。 - user247702
显示剩余5条评论

3
db = new DbContext())
var context= ((Infrastructure.IObjectContextAdapter)db).ObjectContext;
context.Refresh(Core.Objects.RefreshMode.StoreWins, context.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged | EntityState.Modified))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接