1

I had a question pertainning to Parelle and Task in this thread. Previous Question Related to this one

What I am attempting to do is iterate over a collection returned from the entity framework via a sproc.

Everything query's perfectly on the first loop but on the second when I try to skip past the previous query results I'm getting an The result of a query cannot be enumerated more than once error.

I realize the debugger is telling me that I cannot page this collection in this fashion.

How do I use .Skip() and not get that error? I need to be able to iterate over the entire collection until the end is reached.

What's the magic to do this?

Like I mentioned I can loop once, but after that I get that error.

HELP!

ObjectResult<Guid?> memIDs = await Task.Run(() => db.proc_GetCollaborator_UserIDs(projectID));
if (memIDs != null)
{
    while (true)
    {
        var t = memIDs.Take(Environment.ProcessorCount)
                      .Select(id => Task.Run(() => projCollabors.Add(new Collaborator(id.Value, projectID))))
                      .Skip(skip)
                      .ToArray();
        if (t.Length == 0) { break; };
        skip += Environment.ProcessorCount;

        await Task.WhenAll(t);
    };
};
Community
  • 1
  • 1

1 Answers1

3

Your query memIDs.Take(Environment.ProcessorCount) always takes the first Environment.ProcessorCount items from memIDs.

It doesn't "remember" that you took a certain number of items the next time you call .Take on it - it will always start from the beginning again.

Because you're calling it in a loop, memIDs is being repeatedly enumerated. I'm thinking that's where the error is coming from.

You could fix this by turning it into a list like so:

var memIDsList = memIDs.ToList();

And then use memIDsList instead of memIDs.

However, that won't help with your faulty query logic. I assume you're trying to take N items at a time and do something with them?

If so, you could use MoreLinq's Batch extension. (See Create batches in linq for more info about Batch.)

I don't know if using Batch would avoid the need for .ToList(), but you should try it without.

Community
  • 1
  • 1
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276