1

I want to do something similar to below where I am loading in parallel some related data for each of a collection of already loaded entities:

    foreach (var parentThing in ParentThings)
    {
        Context.Load(Context.GetChildThingForParentQuery(parentThing.Id), op =>
            {
                parentThing.Child = op.Entities.FirstOrDefault();
            }, null);
    }

However, it doesn't seem to work. Data is all mixed up in the callback lambda, e.g. parentThing is always the LAST object in the collection and op.Entities always contains only the FIRST child.

user380689
  • 1,766
  • 4
  • 26
  • 39

2 Answers2

1

Think of it this way, because it's asynchronious the time the callback is received the foreach loop has long since passed the current parentThing and this is why you are getting mixed results (Lemans terms, I am sure somebody else will be able to give you a better answer with regards to this).

I have seen in the past it's best to fire these off one by one and wait for the first result before continuing, that way you can keep the last fired parentThing in a global variable or something similar and you will receive back the correct child entity.

    int counter = 0;
    object lastParentThing;

    protected void loopParentThings()
    {
        lastParentThing = ParentThings[counter];
        counter++;

        Context.Load(Context.GetChildThingForParentQuery(lastParentThing.Id), op =>
        {
            lastParentThing.Child = op.Entities.FirstOrDefault();
            loopParentThings()
        }, 
        null);
    }
TBohnen.jnr
  • 5,117
  • 1
  • 19
  • 26
  • Hmm, I think I understand. So there's no easy way to fire all the queries off at once and process each as its completed? – user380689 May 11 '11 at 06:38
  • In this instance yes, you can change it to be an InvokeOperation instead and that way you can pass an object as the state which would be your parent entity and return a single value which is your child entity – TBohnen.jnr May 11 '11 at 06:54
1

The problem with your foreach is caused by accessing a modified closure. Try:

foreach (var temp in ParentThings) 
{
    var parentThing = temp;
    Context.Load(Context.GetChildThingForParentQuery(parentThing.Id), op =>
        {
            parentThing.Child = op.Entities.FirstOrDefault();
        }, null);
}
Community
  • 1
  • 1
Ed Chapel
  • 6,842
  • 3
  • 30
  • 44