renakre
renakre

Reputation: 8291

"Value cannot be null. Parameter name: source" when running a nested query on entity framework

I have the following code where I get error when loading Peers:

Value cannot be null. Parameter name: source

I am using FirstOrDefault and DefaultIfEmpty methods, and inside the select statement I am also checking if the object is empty m => m == null ?. But, I cannot avoid the error. Any ideas?

 ReviewRoundDTO_student results = _context.ReviewRounds
                .Include(rr => rr.ReviewTasks).ThenInclude(rt => rt.ReviewTaskStatuses)
                .Include(rr => rr.Submissions).ThenInclude(s => s.PeerGroup.PeerGroupMemberships).ThenInclude(m => m.User)
                .Include(rr => rr.Rubric)
                .Where(rr => rr.Id == reviewRoundId)
                .Select(rr => new ReviewRoundDTO_student
                {
                    Id = rr.Id,
                    SubmissionId = rr.Submissions.FirstOrDefault(s => s.StudentId == currentUser.Id).Id,
                    Peers = rr.Submissions.FirstOrDefault(s => s.StudentId == currentUser.Id)
                                .PeerGroup.PeerGroupMemberships.DefaultIfEmpty()
                                .Select(m => m == null ? new ApplicationUserDto { } : new ApplicationUserDto
                                {
                                    //FullName = m.User.FullName,
                                    //Id = new Guid(m.UserId)
                                }),

                    }).FirstOrDefault();

Upvotes: 2

Views: 892

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205709

Try avoiding FirstOrDefault().Something construct - expression trees do not support ?. operator which you'd normally use in similar LINQ to Objects query, and EF Core currently has issues translating it correctly - if you look at the exception stack trace, most likely the exception is coming deeply from EF Core infrastructure with no user code involved.

I would recommend rewriting the LINQ query w/o such constructs, for instance something like this:

var results = _context.ReviewRounds
    .Where(rr => rr.Id == reviewRoundId)
    .Select(rr => new ReviewRoundDTO_student
    {
        Id = rr.Id,
        SubmissionId = rr.Submissions
           .Where(s => s.StudentId == currentUser.Id)
           .Select(s => s.Id)
           .FirstOrDefault(),
        Peers = rr.Submissions
            .Where(s => s.StudentId == currentUser.Id)
            .Take(1)
            .SelectMany(s => s.PeerGroup.PeerGroupMemberships)
            .Select(m => new ApplicationUserDto
            {
                FullName = m.User.FullName,
                Id = m.UserId
            })
            .ToList(),
   })
   .FirstOrDefault();

Note that Include / ThenInclude are not needed in projection queries, because they are ignored.

Upvotes: 3

Related Questions