Loading related entities multiple branches and multiple levels

c# entity-framework linq

60 观看

1回复

46 作者的声誉

I'm writing an application where I need the EvaluationRounds with a particular student.

Everything starts with the project. A project has many groups. A group has many members, but one member can also be in many groups. This is done by the associative table ProjectGroupMembers On the other hand, a project has many evaluation rounds.

Currently I have this linq statement:

from r in _context.EvaluationRounds.Include(e => e.EvaluationRoundProject.ProjectGroups.Select(pg => pg.Persons))
                                   .Include(e => e.Evaluations)
     join g in _context.ProjectGroups on r.ProjectId equals g.ProjectId
     join m in _context.ProjectGroupMembers on g.ProjectGroupId equals m.GroupId
     where m.PersonId == studentId && r.EvaluationRoundStartTime < DateTime.Now && r.EvaluationRoundEndTime > DateTime.Now
     select r

We use the using statement to dispose of the dbcontext as soon as we have the list.

The problem is that the EvaluationRoundProject and its relatives are not loaded with the EvaluationRounds. This is what we get:

'((System.Data.Entity.DynamicProxies.EvaluationRound_7400F2ED13550F1E92655A802808E4B94D454A30979C80D0EEED31D0CB7D7005)(new System.Collections.Generic.Mscorlib_CollectionDebugView(activeEvaluationrounds).Items[0])).EvaluationRoundProject' threw an exception of type 'System.ObjectDisposedException'

I have tried:

from r in _context.EvaluationRounds.Include("EvaluationRoundProject").Include(e => e.EvaluationRoundProject.ProjectGroups.Select(pg => pg.Persons)).Include(e => e.Evaluations)
     join g in _context.ProjectGroups on r.ProjectId equals g.ProjectId
     join m in _context.ProjectGroupMembers on g.ProjectGroupId equals m.GroupId
     where m.PersonId == studentId && r.EvaluationRoundStartTime < DateTime.Now && r.EvaluationRoundEndTime > DateTime.Now
     select r

and also

from r in _context.EvaluationRounds.Include(a => a.EvaluationRoundProject).Include(e => e.EvaluationRoundProject.ProjectGroups.Select(pg => pg.Persons)).Include(e => e.Evaluations)
     join g in _context.ProjectGroups on r.ProjectId equals g.ProjectId
     join m in _context.ProjectGroupMembers on g.ProjectGroupId equals m.GroupId
     where m.PersonId == studentId && r.EvaluationRoundStartTime < DateTime.Now && r.EvaluationRoundEndTime > DateTime.Now
     select r

Edit: The evaluations also do not load into the evaluationround

Edit2: this is the whole using code

using (_context = new PeerEvaluationContext())
{
    var activeEvaluationrounds = from r in _context.EvaluationRounds.Include(e => e.EvaluationRoundProject.ProjectGroups.Select(pg => pg.Persons)).Include(e => e.Evaluations)
                                         join g in _context.ProjectGroups on r.ProjectId equals g.ProjectId
                                         join m in _context.ProjectGroupMembers on g.ProjectGroupId equals m.GroupId
                                         where m.PersonId == studentId && r.EvaluationRoundStartTime < DateTime.Now && r.EvaluationRoundEndTime > DateTime.Now
                                         select r;
    return activeEvaluationrounds.ToList();
}

Edit 3: this problem occurs because lazy loading is used. But I went looking on the internet and they said the include part would take care of this.

作者: freshrebel 的来源 发布者: 2017 年 12 月 27 日

回应 1


0

10277 作者的声誉

I suspected that the error occured because of lazy loading. EvaluationRound or EvaluationRoundProject entities have navigation properties which is virtual and EF is attempting to load data in somewhere after _context already disposed. So, would you try to use another class to select query;

var activeEvaluationrounds = from r in _context.EvaluationRounds.Include(e => e.EvaluationRoundProject.ProjectGroups.Select(pg => pg.Persons)).Include(e => e.Evaluations)
    join g in _context.ProjectGroups on r.ProjectId equals g.ProjectId
    join m in _context.ProjectGroupMembers on g.ProjectGroupId equals m.GroupId
    where m.PersonId == studentId && r.EvaluationRoundStartTime < DateTime.Now && r.EvaluationRoundEndTime > DateTime.Now
    select new EvaluationRoundDto
    {
        EvaluationRoundId = r.EvaluationRoundId,
        ProjectId = r.ProjectId
        //etc.
    };

I think you should check virtual navigation properties and where are they used after context already disposed.

作者: lucky 发布者: 2017 年 12 月 27 日
32x32