LivingOnACloud
LivingOnACloud

Reputation: 1261

Querying entity framework in parallel breaks lazy loading

I'm trying to load a lot of records from the DB and I would like to run them in parallel to speed things up.

Below is some example code which breaks when it tries to access the Applicants property which is null. However in a non-parallel loop, Applicants property is either populated or is an empty list, but is never null. Lazy loading is definitely enabled.

var testList = new List<string>();

Context.Jobs
                .AsParallel()
                .WithDegreeOfParallelism(5)
                .ForAll(
                    x => testList.Add(x.Applicants.Count().ToString())
                );

Can I do something like this? Is it related to the entity framework connection? Can I make it parallel friendly and pass an instance of it into the task or something? I'm just shooting out ideas but really I haven't a clue.

Edit:

Is this post related to mine? My issue sounds kind of similar. Entity Framework lazy loading doesn't work from other thread

Upvotes: 1

Views: 7450

Answers (1)

tukaef
tukaef

Reputation: 9214

PLINQ does not offer a way to parallelize LINQ-to-SQL and LINQ-to-Entities queries. So when you call AsParallel EF should first materialize the query.

Furthermore, it doesn't make any sence to parallelize the query that executes on database, cause database can do that itself.

But if you want to parallelize cliend-side stuff, below code may help:

Context.Jobs
.Select(x => x.Applicants.Count().ToString())
.AsParallel()
.WithDegreeOfParallelism(5)
.ForAll(
           x => testList.Add(x)
       );

Note that you can access navigation properties only before the query is materialized. (in your case before AsParallel() call). So use Select to get all what you want.

Context.Jobs
.Select(x => new { Job = x, Applicants = x.Applicants })
.AsParallel()
.WithDegreeOfParallelism(5)
.ForAll(
       x => testList.Add(x.Applicants.Count().ToString())
   );

You also can use Include method to include navigation properties into results of the query...

Context.Jobs
.Include("Applicants")
.AsParallel()
.WithDegreeOfParallelism(5)
.ForAll(
       x => testList.Add(x.Applicants.Count().ToString())
   );

Upvotes: 2

Related Questions