none
updating EF cache/context when database changes RRS feed

  • Question

  • Hello,

    Is there a way to get Entity Framework to update its cache/context after a change has been made to the database?

    I understand that this would usually be automatic if the change to the database is done through EF, but this seems not to be the case with stored procedured. What I mean is, we have a stored procedure for deleting a whole bunch of data from the database, and I *think* the call to the stored procedure is handle by EF (though I'm not 100% how that works), but after the call to the stored procedure returns, I check the EF cache/context and find all the data still there.

    Therefore, I'm looking for a way to tell EF to update its cache/context based on the current state of the database. Is there a way to do this?
    Thursday, March 8, 2018 7:49 PM

All replies

  • Hi gib898,

    You could refresh an EF context after your changed db data in a stored procedure. like this:

    public void Refresh()
    {
    
                var ctx = ((IObjectContextAdapter)this).ObjectContext;
    
                // Get all objects in statemanager with entityKey 
                // (context.Refresh will throw an exception otherwise) 
                var objects = (from entry in ctx.ObjectStateManager.GetObjectStateEntries(
                                                           EntityState.Added
                                                          | EntityState.Deleted
                                                          | EntityState.Modified
                                                          | EntityState.Unchanged)
                                          where entry.EntityKey != null
                                          select entry.Entity);
    
                ctx.Refresh(RefreshMode.StoreWins, objects);
    }

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by gib898 Tuesday, March 20, 2018 5:39 PM
    • Unmarked as answer by gib898 Tuesday, March 20, 2018 7:30 PM
    Friday, March 9, 2018 6:42 AM
    Moderator
  • Hi gib898,

    You could refresh an EF context after your changed db data in a stored procedure. like this:

    public void Refresh()
    {
    
                var ctx = ((IObjectContextAdapter)this).ObjectContext;
    
                // Get all objects in statemanager with entityKey 
                // (context.Refresh will throw an exception otherwise) 
                var objects = (from entry in ctx.ObjectStateManager.GetObjectStateEntries(
                                                           EntityState.Added
                                                          | EntityState.Deleted
                                                          | EntityState.Modified
                                                          | EntityState.Unchanged)
                                          where entry.EntityKey != null
                                          select entry.Entity);
    
                ctx.Refresh(RefreshMode.StoreWins, objects);
    }

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thanks Zhanglong,

    That works!

    Let me see if I understand each step:

    var ctx = ((IObjectContextAdapter)this).ObjectContext;

    Getting the ObjectContext from the DbContext. The ObjectContext does all the work while the DbContext is just a wrapper.

    var objects = (from entry in ctx.ObjectStateManager.GetObjectStateEntries(
                                                           EntityState.Added
                                                          | EntityState.Deleted
                                                          | EntityState.Modified
                                                          | EntityState.Unchanged)
                                          where entry.EntityKey != null
                                          select entry.Entity);

    Get a bunch of ObjectStateEntries. Get all those whose state is Added, Deleted, Modified, and Unchanged from the EF cache. For my purposes, I avoided EntityState.Added because it gave me an error and the added entities aren't in the database at this point.

    ctx.Refresh(RefreshMode.StoreWins, objects);

    Refresh the ObjectContext (and thus the DbContext as well) from the database. Use the ObjectStateEntries you just got to determine which objects to refresh. Since my stored procedure deleting a whole bunch of entities in the database, the unchanged entities in the cache will be updated to deleted (or 'detached' as my tests seem to show). Since this is done on a per-object basis (as opposed to the entire cache) the newly added entities are not touched.

    Is this right?

    Tuesday, March 20, 2018 5:49 PM
  • Sorry Zhang, I'm going to have to unmark this as the answer.

    Apparently, this context refresh thing only works on nodes.

    In my EF hierarchy, I have nodes as parent objects, deviations as child object under nodes (in a 1-to-many relation), and several other levels of objects under deviations.

    My preliminary test showed that the method works for nodes. Before the method is run, I see all the old nodes in the database. After it is run, I see only the new nodes. This is what I want.

    But I also want the same for deviations and everything under that. Before the method is run, I see all my old deviations in the database. After the method is run, I see no deviations in the database.

    Oddly enough, if I check the EF cache while debugging, I can see deviations under the nodes. They're state is Added. Then when I let it run to completion and check the database, I see only the deviations I checked while debugging... as if checking the state of new entities in code has an effect on whether they get added to the database or not.

    Tuesday, March 20, 2018 7:35 PM
  • Hi gib898,

    It seems that you create a new thread, please refer to the new thread. https://social.msdn.microsoft.com/Forums/en-US/fe9e1be6-1438-4748-b934-1d3e67b775e8/why-is-this-method-for-refreshing-ef-cache-not-working?forum=adodotnetentityframework

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 21, 2018 2:37 AM
    Moderator