【发布时间】:2019-04-01 21:47:09
【问题描述】:
我正在使用 vb.net 2017、Entity Framework 6 和 sql server 2018R2。 我有一个表 TB1(id , name , value1) 我得到数据:
myquery=(From t in context.tb1s select t).tolist
现在,myquery 有一个包含这些值的记录:name=Name1 , value1=5
另一个用户在另一台PC上运行相同的程序,在数据库上的这条记录上进行更改,value1=10。他将更改保存在数据库中。
在我的表单上,我有一个“刷新”按钮,它再次执行我的第一个查询:
myquery=(From t in context.tb1s select t).tolist
但是在那条记录上,value1 仍然是 5 并且没有得到更新的值。 当其他用户创建新记录或删除现有记录时,我没有问题。当我按下刷新按钮时,所有这些更改都会反映出来。但是当记录更新时,我总是有旧值。
我怎样才能解决这个问题不处理上下文?
谢谢!
编辑 我找到了 2 种通用方法来解决此问题而无需处理上下文(使用新值从数据库中刷新实体及其子项)
方法一
For Each en As tb1 In tb1collection
context.Entry(en).Reload()
For Each chld In en.mychilds
context.Entry(chld).Reload()
Next
Next
方法 2
For Each en As tb1 In tb1collection
For i= en.mychilds.count-1 to 0 step -1
context.Entry(en.mychilds(i)).State = EntityState.Detached
Next
context.Entry(en).State = EntityState.Detached
Next
context.tb1s.Include("mychilds").Load
问题是当要刷新的实体集合非常大时,这两种方法都非常慢。 我能做什么?
【问题讨论】:
-
为什么不想处理上下文?
DbContext被设计为短暂的;您应该将其包装在Using块中并每次都对其进行初始化。如果你真的想避免因为某种原因释放上下文变量,你可以看看this question;它是关于 C# 的,但想法是一样的。您会注意到,当您拥有导航属性时,事情会变得更加复杂,这表明更简单的解决方案是始终处理您的上下文变量。 -
@AhmedAbdelhameed 我不想处理上下文,因为在我的表单上我已经加载了很多其他实体,我不想再次加载所有的东西。
-
您不必这样做。让你的上下文成为一个局部变量而不是一个类级别的变量,加载你想要的一切,然后处理它。当你想“刷新”时,创建一个新的上下文并只加载你想刷新的条目;其他一切都将保持不变。
-
@AhmedAbdelhameed 我处理上下文的情况如何,创建一个新的并加载一些条目。如果我更新使用旧上下文加载的另一个实体中的另一个条目怎么办。新上下文是否知道这些条目并可以保存更改?
-
@AhmedAbdelhameed 我刚刚测试过。我已经创建了一个新的上下文,并且我已经加载了一些实体。在我更改了使用旧上下文加载的另一个记录之后。当我按下保存更改时,更改不会保存到数据库中。