0

I'm using vb.net 2017 , Entity Framework 6 and sql server 2018R2. I have a table , TB1(id , name , value1) I get the data :

myquery=(From t in context.tb1s select t).tolist

Now , myquery has a record with these values : name=Name1 , value1=5

Another user that run the same program on another PC , make a change on this record on database , value1=10. He save the changes on database.

On my form i have a button "Refresh" that execute again my first query :

myquery=(From t in context.tb1s select t).tolist

But on that record , the value1 is still 5 and does not get the updated value. I have no problems when the other user create a new record , or delete an existing record. When i press my Refresh button all these changes are reflected. But when a record is updated , i have always the old values.

How can i resolve this problem WITHOUT DISPOSING THE CONTEXT ?

Thank you !

EDIT I've found 2 general methods to resolve this without disposing the context ( to refresh entity and its child from database with new values )

METHOD 1

For Each en As tb1 In tb1collection
    context.Entry(en).Reload()
    For Each chld In en.mychilds
       context.Entry(chld).Reload()
     Next
Next

METHOD 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

THE PROBLEM IS THAT BOTH METHODS ARE VERY SLOW WHEN THE COLLECTION OF ENTITIES TO BE REFRESHED IS VERY LARGE. WHAT CAN I DO ?

antoni
  • 1
  • 6
  • 1
    Why do you not want to dispose the context? `DbContext` is designed to be short-lived; you should wrap it in a `Using` block and initialize it every time. If you really want to avoid disposing the context variable for some reason, you may look at [this question](https://stackoverflow.com/q/20270599/4934172); it's about C# but the idea is the same. You'll notice that things get more complicated when you have navigation properties which indicates that the easier solution is to always dispose of your context variable. – 41686d6564 stands w. Palestine Apr 01 '19 at 23:24
  • @AhmedAbdelhameed I don't want to dispose the context because on my form i have loaded a lot's of other entities and i don't want to load all the things again. – antoni Apr 01 '19 at 23:33
  • You don't have to. Make your context a local variable instead of a class-level variable, load everything you want, and then dispose of it. When you want to "refresh", create a new context and load _only_ the entries you want to refresh; everything else will stay the same. – 41686d6564 stands w. Palestine Apr 01 '19 at 23:38
  • @AhmedAbdelhameed What about the case that i dispose the context , create a new one and load some entries. What if i update another entry in another entity that was loaded using the old context. Does the new context know about these entries and can save changes ? – antoni Apr 02 '19 at 10:48
  • @AhmedAbdelhameed I've just tested. I have create a new context and i have load some entities. After i've changed anther record that was loaded using old context.When i press save changes , the changes are not saved to database. – antoni Apr 02 '19 at 11:16
  • Because the new context knows nothing about the _local_ entity. You need to update the values using the new context so that it matches the updated entity. [There are several ways to do so](http://kerryritter.com/updating-or-replacing-entities-in-entity-framework-6/); the easier one, **if you don't have navigation properties**, is `context.Entry(someEntity).CurrentValues.SetValues(updatedEntity)`. – 41686d6564 stands w. Palestine Apr 02 '19 at 14:02
  • Again, [you do not want to keep the context alive for the lifetime of the application](https://stackoverflow.com/a/14526484/4934172). It might seem easier for you at first but once you get used to the "proper way", it'll save you a lot of trouble. The DbContext is meant to be disposed of for a reason. – 41686d6564 stands w. Palestine Apr 02 '19 at 14:09
  • @AhmedAbdelhameed I have navigation properties , but if i have to update one by one all the entities with new values , then i can just use one of 2 methods on my updated questions. The problems is that it's a slow process. – antoni Apr 02 '19 at 17:43

1 Answers1

0

This is working :

Dim contextobj = (CType(context, IObjectContextAdapter)).ObjectContext
contextobj.Refresh(RefreshMode.StoreWins, context.tb1s.Local)
contextobj.Refresh(RefreshMode.StoreWins, context.mychilds.Local)
antoni
  • 1
  • 6