none
How to refresh instance of entity at client side with wcf ria service?

    Question

  • Suppose I have an entity myClass with property P1. I inserted one row to table myClass with P1=null by Stored Procedure.

    After that, I did something else to update P1=1 by ria service. It is fine and data was saved to DB. Then I load myClass again using Context.Load with LoadBehavior.RefreshCurrent, at server side, I can see the data P1=1 is loaded. but at client side in completed event, P1 value is still null, not 1.

    If I rerun the app with no code change, then I can see P1 =1 is loaded.

    but for those data updated with Generated code with DomainService, not by SP, above Context.Load with LoadBehavior.RefreshCurrent is working fine

    Not sure why. How to force DomainContext to get lastest data from service side?

    Thursday, October 27, 2011 10:34 AM

All replies

  • I had the same issue i tried whatever solution mentioned in the forum nothing worked out finally i used the RefreshInterval propert of the domain data source. Before loading the data set the domaindatasource interval to 1 sec

    DomainDataSource.RefreshInterval =new TimeSpan(0,0,1);

    Then once loaded in the LoadedData event set the timespan back to 0,0,0 its like reset

    private void projectDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)

    {this.projectDomainDataSource.RefreshInterval = new TimeSpan(0, 0, 0);

    }

    The RefreshInterval will refresh the data for every timespan. So setting it to 0,0,0 will reset else it will keep refreshing the data every sec. 

    Thursday, October 27, 2011 2:08 PM
  • Thank you. I don't use DomainDataSource. I use DomainContext and load data like:

      Context.Load<T>(qry, LoadBehavior.RefreshCurrent, r =>
                {
                    if (evt != null)
                    {
                        try
                        {
                            if (r.HasError)
                            {
                                evt(this, new EntityResultsArgs<T>(r.Error));
                                r.MarkErrorAsHandled();
                            }
                            else
                            {
                               
                                evt(this, new EntityResultsArgs<T>(r.Entities));
                            }                        
                        }
                        catch (Exception ex)
                        {
                            evt(this, new EntityResultsArgs<T>(ex));                        
                        }                    
                    }

    At server side, I can see all data refreshed with the right value, but when I captured result from r.Entities with completed, the data different from the server side data. Can't understand.

    Monday, November 07, 2011 10:18 AM
  • Did u try my approach?

    Wednesday, November 16, 2011 2:37 AM
  • Thanks for you answer. RefreshInterval is only avaliable for DomainDataSource, not for DomainContext.

    Wednesday, November 16, 2011 9:09 AM
  • What type is the P1 object? I have never seen LoadBehavior.RefreshCurrent fail to load new data. The one instance I can find of someone with that problem was where they were not waiting for the load to complete. Have you tried using Fiddler to see what is going to the client?

    Wednesday, November 16, 2011 9:38 AM
  • What type is the P1 object? I have never seen LoadBehavior.RefreshCurrent fail to load new data. The one instance I can find of someone with that problem was where they were not waiting for the load to complete. Have you tried using Fiddler to see what is going to the client?

    Thanks for your comment, Colin.

    This case is happing in my app everywhere.  No problem with SP. Here is my codes in detail:

    At server side, a domain service is something like:

     public IQueryable<Person> GetPersonByID(int id)
            {
                var result = this.ObjectContext.Persons.
                    Where(e => e.PersonID == id);
                return PersonEagerLoading(result).AsQueryable<Person>(); // check point 1
            }


       private static List<Person> PersonEagerLoading(IEnumerable<Person> results)
            {
                List<Person> temps = new List<Person>(results);
                foreach (Person p in temps)
                {
                    p.DepartmentReference.Load();                
                }

                return temps;
            }


    At client side, I make a call in following way(this is call by a button I called it refresh button):
    this._amsService.Context.Load<Person>(
        this._amsService.Context.GetPersonByIDQuery(this.Person.ID),
        LoadBehavior.RefreshCurrent,
        result =>
        {
            this.Person = result.Entities.FirstOrDefault(); //check point 2
            this.RaisePropertyChanged("Person");     
            
        }, null);
       

    here is my trying:

    Suppose I have a person in DB with data say personID=1, Age = 16.

    1. Then run the app, I get the data in the right way.

    2. then go to database,  update data with SQL to change Age = 20.

    3. Then back to app and click on refresh button to make a new call, but the age is not updated to 20, it is still 16.

    I run the app in debug mode, and check the data:

    At check point 1, I check data in result, it is fine, Age = 20

    At check point 2, I check data in result.Entities, the data not refreshed, still get Age = 16.

    I don't understand why. I also try to use fiddler to catch the data when click on refresh button, but the data is not readable. only property name in plain text.

    How to resolve this problem? it is a big problem for LOB app in this case.

    Friday, December 02, 2011 11:16 AM
  • Regarding Fiddler, check the Fiddler website for the WCF Binary decoder. It will allow you to read what RIA Services is sending.

    Friday, December 02, 2011 4:06 PM
  • Thank you. After install wcf binary decoder for fiddler, I can see the data in fiddler when making async call on wcf service.

    Interesting thing is the data in fiddler is the latest data. It is age = 20, the right value updated with sql.

    So I am confused here: why this new data can't be captured in result.Entities in completed event?

    This case is only happen when use entites with linq to get data. If I use SP with complex object for result, no problem. I can get the latest data with any async call on domain service.

    Saturday, December 03, 2011 9:01 AM
  • Hello, did you ever find a solution to your problem.

    I am seeing the exact same issue, I have a stored procedure that runs and updates several objects and returns one set of objects, so I have to load the other objects that get modified and I use the Load with refreshcurrent and the new values seem to come across sometines? Even though I test the same object and the same process everytime. Fiddler always shows that the value is being retrieved correctly in the WCF binary inspector.

    Is this some really big bug??? We have ran across other silverlight issues that do not seem to be something that Microsoft even plans on addressing, even thought they are in the existing RC 4 version of Silverlight!!!! So should we all just stop any Silverlight development and do something else, what are we supposed to say to our clients, sorry but it just does not work somethings, and oh that, yes well we have to make sure all comboboxes are bound to non-null values, otherwise the binding gets wiped out when you go between to objects where one has a value and the other is null, what?! I am really getting frustrated with Silverlight and Ria and that is what the client chose, but they could not even back up why they chose it and now everyone has had nothing but problems.  

     

     

    Thursday, December 08, 2011 1:11 PM
  • Colin, I have the exact same issue as Kent.

    It seems there has still not been a solution suggested that works. Do you have any other suggestions as to why the Load operation with RefreshCurrent does not work as expected?!  I have no choice but to use a stored procedure to update multiple objects in my database so I have to reload those changed and the updates are not coming across to the client side context.

    Thursday, December 08, 2011 1:13 PM
  • If you can create a small solution showing the problem and upload it somewhere I will take a look and see if I can find the problem.

    Thursday, December 08, 2011 1:23 PM
  • Thanks for your quick response!

    In all honestly, I don't think my solution would help find the problem. Because at times I test and it works as it should at other times it does not and I am testing the same entity and sproc, I simply update the value of a column being set in the sproc so that it is different than the current value loaded in my context, and sometimes the context on the client side of my silverlight application gets the right value loaded into the entity and other times it does not? I am at my wits end and do not know what to tell my client about this. Have others seen this inconsistency, Kent had the issue but I do not know that he ever saw the correct behaviour or not.

    Thursday, December 08, 2011 1:52 PM
  • What I can do is tell you how I would debug this if I were you in your place.

    I would install Red-Gate's reflector (http://www.reflector.net/) and use its Visual Studio integration features to debug into the code of RIA Services itself to find out what is happening. For this particular problem put your breakpoint in EntitySet's internal IEnumerable<Entity> LoadEntities(IEnumerable<Entity> entities, LoadBehavior loadBehavior). You can then drill down from there to follow the entities in question as they get processed.

    Also, I can't remember if I already mentioned this, but if this were happening to me I would be suspicious that I have multiple instances of the DomainContext in my application and that the one loading new data is different then the one that owns the previously loaded entity. I would also check the entity I already have to make sure that the EntityState is not Detached.

    Thursday, December 08, 2011 2:06 PM
  • Thanks Colin! You are a great help and I will look into Redgate's reflector.

    I have kept debugging and I have found that if I new up an instance of my domaincontext after my stored procesdure has updated the entity in the database, and load that entity into the new context, it always loads fine with the correct values. Soooo, the issue seems to be when I try to load Entity into the context that already contains the entity that the entity does not always get refreshed as it should. I just emailed another consultant who engineered the base classes for all of our viewmodels to let him know what i found, as it seems that it could be something in our core objects messing up the load somehow. I am hoping he can help me out more, in the meantime I will try to get the redgate reflector installed and see what it shows me.

     

    Thanks again!

    Thursday, December 08, 2011 3:15 PM
  • I have downloaded SP2 and try above code again. Same as before. No solution yet. It is a really big issue as my project almost done. I use Tab for data form. user can open/close tab. So even data was changed in DB or by other users, if current user open tab again(make a async call to get data), data is not updated.

    Help please!

    Friday, December 09, 2011 10:11 AM
  • Help please!

    Kent, same guidance for you. Either provide me a demo solution showing the problem or use Reflector to see if you can find out what is going on.

    Friday, December 09, 2011 10:26 AM
  • yes well we have to make sure all comboboxes are bound to non-null values, otherwise the binding gets wiped out when you go between to objects where one has a value and the other is null, what?!

    Kyle McClellan wrote some extensions to the Combbox that help with problems like that. Details at http://blogs.msdn.com/b/kylemc/archive/2010/06/18/combobox-sample-for-ria-services.aspx.

    Personally, I use the Telerik combbox as the one included with Silverlight is, quite frankly, awful.

     

    Friday, December 09, 2011 10:38 AM
  • Thank you, Colin. Will do and let you know what I can find.

    Friday, December 09, 2011 12:22 PM
  • Yes have gone to Telerik for comboboxes where I need to allow null values. But Telerik controls do not align right in a dataform at all for some reason, so I was not able to utilize them inside my dataform templates, because no matter what I tried they were never rendered where I wanted them. Pain.

    Friday, December 09, 2011 2:50 PM
  • Help please!

    Kent, same guidance for you. Either provide me a demo solution showing the problem or use Reflector to see if you can find out what is going on.

    Hi Colin,  I have tried Reflector to trace data in debug mode. Here is the result:

    The debug assembly is System.ServiceModel.DomainServices.Client.Web. Here is the disassemble code for Load completed event:

    private void CompleteLoad(IAsyncResult asyncResult)
        {
          LoadOperation operation = (LoadOperation) asyncResult.get_AsyncState();  //Check point here
          IEnumerable<Entity> entities = null;
          IEnumerable<Entity> allEntities = null;
          int totalEntityCount = -1;
          if (!operation.IsCanceled)
          {
            Exception error = null;
            QueryCompletedResult result = null;
            try
            {
              lock (this._syncRoot)
              {
                result = this.DomainClient.EndQuery(asyncResult);               //Check point 1
                entities = Enumerable.Cast<Entity>(this.EntityContainer.LoadEntities((IEnumerable) result.Entities, operation.LoadBehavior));       //Check point 2
                IEnumerable<Entity> enumerable3 = Enumerable.Cast<Entity>(this.EntityContainer.LoadEntities((IEnumerable) result.IncludedEntities, operation.LoadBehavior));
                allEntities = Enumerable.Concat<Entity>(entities, enumerable3);
                totalEntityCount = result.TotalCount;
              }
            }
            catch (Exception exception2)
            {
              if (exception2.IsFatal())
              {
                throw;
              }
              error = exception2;
            }
            finally
            {
              this.DecrementLoadCount();
            }
            if (error == null)
            {
              if (Enumerable.Any<ValidationResult>(result.ValidationErrors))
              {
                operation.Complete(result.ValidationErrors);
              }
              else
              {
                DomainClientResult result2 = DomainClientResult.CreateQueryResult(entities, allEntities, totalEntityCount, result.ValidationErrors);     //Check Point 3
                operation.Complete(result2);
              }
            }
            else
            {
              operation.Complete(error);
            }
          }
        }

    After change data with SQL manually in database, then I click on refresh button:

    1.Check point 1: Check the property value: it is the new data, Age = 20

    2. Check point 2: Check the property value: it is the old data, Age = 16

    3. Check point 3: Check the property value: it is the old data, Age = 16

    So the final value returned is old value Age = 16.

    Although in check point 2, the operation.LoadBehavior is RefresCurrent, but object is not updated to new value.

    Friday, December 16, 2011 9:35 AM
  • Kent, that isn't where I suggested you put the breakpoint to find what is happening.

    Friday, December 16, 2011 11:12 AM
  • Sigh... I've been running into the same issue, sadly. I was about to reply to this thread about a month ago. But for the heck of it I recreated my project and the problem mysteriously disappeared although I didn't actually change any code. The last couple of days it reared its ugly head again. There seems to be a random aspect to it. Earlier this evening I walked it through in the debugger with hopes of finding something I missed in my many previous attempts of nailing it down, but the issue didn't appear. Then I ran it again a few minutes later and the issue came back - with no code changes!

    In all cases Fiddler shows my newly updated information coming back, however the entity on the client is still the old one. Using LoadBehavior.RefreshCurrent has no noticable effect. BTW... I confirmed my context has no changes pending and no errors were returned from the load operation callback. Below is the code (taken directly from an online sample). Pretty straight forward. I only have 1 domain context in case you're wondering. In case it matters, this code is in a RIA Services library. Seems like a RIA services issue to me as it seems to fail somewhere between the data being returned and my callback.

                _pendingLoads[typeof(T)] = _context.Load(query, LoadBehavior.MergeIntoCurrent, lo =>
                {
                    _pendingLoads.Remove(typeof(T));
                    callback(lo);
                }, state);
    


    Any ideas for next steps?

    P.S. Thanks for all of your posts, Colin. Your responses to so many other threads have solved more problems I've encountered than I can count on both hands!

    Friday, February 17, 2012 7:44 PM
  • Update... I had another look at this thread and found a response by Colin that I initially missed to have a look at the RIA Services internals. I've installed Reflector and loaded the assembly. Now I just need to figure out how to set the breakpoint in EntitySet's internal IEnumerable<Entity> LoadEntities(IEnumerable<Entity> entities, LoadBehavior loadBehavior) as mentioned by Colin above. Can't wait to figure this out! When I do, I'll post the issue back here.

    Tuesday, February 21, 2012 8:44 AM
  • Ok, I've gotten a little further. After I hooked up .NET Reflector to RIA Services I found that I needed to turn off exceptions because it was throwing like crazy, complaining about Invalid object name for dbo.EdmMetadata. Best I can tell is that it doesn't like something about EF Code First. Apparently they are all caught and handled in RIA Services code as the execution seems to continue on and no errors are reported. 

    Anyway, I debugged into RIA Services beginning at the EntitySet's internal IEnumerable<Entity> LoadEntities(IEnumerable<Entity> entities, LoadBehavior loadBehavior) and I saw nothing out of the ordinary. The LoadBehavior was appropriately still set to MergeCurrent. No errors are reported. No exceptions are thrown here. After stepping through a bit more it goes into EntityContainer at which point I lose debug information and intellisense which makes it far harder to figure out what's going on. I'm curious as to why I lose it. It looks like I'll need to step into some of the deeper methods because stepping through at the higher level eventually drops me back into my callback with the stale entity and it appears as if everything worked correctly from the supporting information in the query result.

    Wednesday, February 22, 2012 11:08 AM
  • Debugging with Just My Code turned off and break on exception turned on is not fun. There are a lot of exceptions happening in the background which are just expected.

    If you can't debug further it means there are some dlls that are not marked in reflector to be debugged. When you see something you can't debug into, right click on it and Go To Definition. That will take you to the class and then you can figure out what dll isn't marked.

    Wednesday, February 22, 2012 11:42 AM
  • Figured it out... It turns out that the entitities were editable, although they had no changes. The reason is that the base view model class in the MVVM toolkit I'm using supports IEditableObject by default. Just creating the ViewModel actually opens the model for editing. This makes sense in many cases. However, in my case, I needed the ViewModel to enable double-click support for list items which I did by wrapping each item template with a ViewModel. Every item displayed was essentially in edit mode. To fix my issue, I found a constructor on the ViewModel base class that takes a bool for whether to support IEditableObject on the model properties. I turned it off and all is well again.

    Wednesday, February 22, 2012 4:13 PM
  • That's good to know, Colin. I'm also glad you mentioned .NET Reflector and the appropriate place in RIA Services to put a break point. I don't know that I would have figured it out otherwise. It really had me stumped! Thank you!

    Wednesday, February 22, 2012 4:17 PM
  • Excellent, glad that you found the culprit. What MVVM toolkit were you using?

    Friday, February 24, 2012 6:36 AM
  • Catel. I've been quite please with the framework overall.

    Friday, February 24, 2012 10:07 AM