可能的参考资料
我发现了一个类似的问题:Refreshing a SQL database connection没有提出解决方案(更多检查代码)
和LINQ to SQL does not update when data has changed in database应该更接近我的问题。
设置
我允许用户在运行时更改连接字符串(通过SqlConnectionStringBuilder,EntityConnectionStringBuilder和“New EntityClient.EntityConnection(entityconn())”) 我使用.Open的EntityConnection和“New Database.DatabaseContainer(entityConnection)”
我一直使用相同的容器来读取数据库数据。并且用于调用“.SaveChanges”并且到目前为止还没有明确使用事务。 (我希望“SaveChanges”能够自动执行提交并在提交之前如果缓存数据已更改则抛出异常)
问题说明
当我执行2个程序并用一个程序更改数据时,另一个程序在另一个程序提交之前建立连接时没有注意到这些更改。
例如,如果我有2次相同的程序(A和B),则会发生以下情况: 启动A,启动B,更改A中的数据,B无法读取更改的数据(因为它在A完成更改之前启动了连接)。
问题
如何刷新本地缓存数据,以及如何处理赛车问题?
当我刷新A的连接然后更改数据时,同时B刷新并且也开始更改数据,然后B可能会覆盖A的更改而不会注意到。刷新后更改数据库时会发生这种情况。我上面提到的第二个问题似乎不是要解决这个问题。
我猜想我可以如何解决问题
也许命令“Container.Refresh(Objects.RefreshMode.StoreWins,entity)可能对此有所帮助,但我不确定将什么对象作为实体给出。我刚从缓存的数据库中读取过时的那个?并且是tere仍然是问题,我不确定何时会发生冲突。
也许它应该与事务或更改事务管理器有所不同,确保所有更改都只进行(或反复尝试进行),直到事务开始后数据库中没有更改?这是可能的,或者如何处理已经被活动交易的另一个程序改变的数据?
答案 0 :(得分:1)
您看到的是identity map行为,它是EF的核心功能。
要解决刷新问题,您可以使用
<强>刷新强>
objectContext.Refresh(RefreshMode.StoreWins, entity);
entity
是先前从您想要刷新的数据库中检索的对象。
<强> MergeOption 强>
objectContext.YourEntitySet.MergeOption = MergeOption.OverwriteChanges;
var data = objectContext.YourEntitySet.
/* Any query you want to execute to refresh your data */
ToList();
MergeOption
控制数据读取到身份地图的方式。默认设置为AppendOnly
,它将仅实现以前未加载的实体,但已加载的实体将保持不变 - 这是核心功能,因为否则任何查询都将能够覆盖未保存的状态。
第二个问题与您最初的问题完全无关。如果您担心一个应用程序在准备其他应用程序中的修改期间可以更改数据,则需要处理concurrency。
答案 1 :(得分:0)
我不确定这是否会对EF有所帮助,但请看SqlDependency:
“SqlDependency允许您在数据库中的原始数据发生更改时接收通知,以便可以刷新缓存。”