实体框架查询返回的结果少于预期

时间:2015-04-09 17:06:44

标签: c# asp.net-mvc linq entity-framework entity-framework-6

我有一个实体框架查询,我在那里计算一些学生的成绩。查询如下:

(
    from s  in Students.Where(a => a.GroupId == groupId)
    from q  in Quizzes.Where(a => a.GroupId == groupId)
    from qa in QuizAnswers.Where(a => a.UserId == s.UserId && a.QuizId == q.QuizId).DefaultIfEmpty()
    select new Response
    {
        UserId       = s.UserId,
        UserFullName = s.FullName,

        ActivityType = "Quiz",
        ActivityId   = q.QuizId,
        ActivityName = q.Name,
        DueDate      = q.DueDate,
        Score        = qa == null ? null : qa.Score,
        MaxScore     = qa != null ? qa.MaxScore ?? 0 : 0,
        IsSent       = qa != null && qa.DateSent != null,
    }
)
.OrderBy(a => a.DueDate).ThenBy(a => a.ActivityId)
.AsEnumerable()
.GroupBy(a => new User
{
    a.UserId,
    a.UserFullName,
})

此查询加入所有学生和所有测验。我没有直接查询QuizAnswers,因为如果学生没有打开测验,它还不存在,但我需要一个占位符来显示在报告卡上。

现在,当我在LinqPad上运行它时,查询正常工作。在我正在进行的示例中,它显示了4个测验和700个学生,并且所有条目都被正确检索。

但是,在应用程序(它是一个ASP.NET MVC 4应用程序)上放置相同的查询,在迭代查询时,它会显示所有700名学生,但只显示第一个测验。我也试过添加和删除测验,但它总是只显示第一个。

由于LinqPad正确运行查询,是否有任何实体框架或ASP.NET MVC采取不同的做法?可能是优化,还是配置还是什么?

2 个答案:

答案 0 :(得分:1)

问题是我在LinqPad和Visual Studio中都没有运行完全相同的查询。

在LinqPad中,我有GroupBy(a => new { /* stuff */ }),而在Visual Studio中我有GroupBy(a => new User { /* stuff */ }),其中User是不属于实体框架的类。

正如我后来发现的那样,GroupBy需要一个具有重写等式的类,匿名类具有该类,但我的自定义类没有。

解决方案是覆盖Equals定义中的User

答案 1 :(得分:0)

在VS GroupBy中应为Type

稍微改变查询的顺序。

改为:

  from tt in ( from s in Folder.Where(a => a.GroupId == groupId)
   from q in Quizzes.Where(a => a.GroupId == groupId)
   from qa in QuizAnswers.Where(a => a.UserId == s.UserId && a.QuizId == q.QuizId).DefaultIfEmpty()
   )
    group tt by new {a.UserId, a.UserFullName}
     into grp
   select new
   {
       UserId = grp.tt.UserId,
       UserFullName = grp.tt.FullName,

       ActivityType = "Quiz",
       ActivityId = grp.tt.QuizId,
       ActivityName = grp.tt.Name,
       DueDate = grp.tt.DueDate,
       Score = grp.tt == null ? null : grp.tt.Score,
       MaxScore = grp.tt != null ? grp.tt.MaxScore ?? 0 : 0,
       IsSent = grp.tt != null && grp.tt.DateSent != null,
   }
   )

   .OrderBy(a => a.DueDate).ThenBy(a => a.ActivityId)
   .AsEnumerable()