使用subselect优化linq to sql查询以获取最新结果

时间:2010-12-29 14:56:33

标签: c# linq-to-sql

我将测验的结果存储在表格中,我需要找出针对用户特定测验的所有问题的最新答案ID(每行都有id,quizid,questionid,answerid,username和datecompleted )。

我已经成功了,但它太丑了我以为我会请求帮助来优化它。我提前开始新的一年决议,写出质量更好的代码! :)所以,如果有人想告诉我如何优化它,将非常感激!

public List<QuestionResult> GetLatestResult(Guid QuizID, string UserName)
    {
        List<QuestionResult> quizResult = new List<QuestionResult>();

        // first get all question ids for that quiz
        var questionIDs = (from q in db.QuizResults
                          where (q.QuizId == QuizID && q.UserName == UserName)
                          select q.QuestionId).Distinct();

        // then get the most recent answer id for those questions
        var results = from r in questionIDs
                      select (from q in db.QuizResults
                              where q.QuizId == QuizID
                              && q.UserName == UserName
                              && q.QuestionId == r
                              orderby q.DateCompleted descending
                              select q).Take(1);

        foreach (var item in results)
        {
            foreach (var qr in item)
            {
                QuestionResult result = new QuestionResult();
                result.QuestionId = qr.QuestionId;
                result.AnswerId = qr.AnswerId;
                quizResult.Add(result);
            }
        }

        return quizResult;
    }

这是C#,linq to sql,如果您需要更多详细信息,请告诉我。

谢谢,

Annelie

2 个答案:

答案 0 :(得分:2)

var questionIDs分配可能会被删除 - 您已在第二个分配QuizIDUserName

可以使用组重写第二个查询,以便整个函数变为一个LINQ:

public List<QuestionResult> GetLatestResult(Guid QuizID, string UserName) {
    return (
           from q in db.QuizResults
           where q.QuizId == QuizID && q.UserName == UserName
           group q by q.QuestionId into grouped
           select new QuestionResult {
               QuestionId = grouped.Key,
               AnswerId = grouped.OrderByDescending(q => q.CompletionDate).First().AnswerId
           };
       ).ToList();
}

修改

不要担心q变量被使用两次 - 首先group q by q.QuestionIdq超出范围,并且可以再次使用此名称。

答案 1 :(得分:0)

以下是我对此的攻击方式。第一个查询将给出用户进行测验的最近时间。第二个查询将获得该测验的结果,选择进入IEnumerable。查询只是为了便于阅读而拆分,它们可以与第一个查询组合在一起作为第二个查询。

public List<QuestionResult> GetLatestResult(Guid QuizID, string UserName)     
{         
    // get the latest date that this user took this quiz
    var latestQuizDate = (from q in db.QuizResults 
                          where q.QuizId == QuizID
                              && q.UserName == UserName
                          select q).Max(q => q.CompletionDate);

    // get the quiz results for this user/quiz/date 
    var results = from q in db.QuizResults
                  where q.CompletionDate = latestQuizDate
                      && q.QuizId == QuizID
                      && q.UserName == UserName
                  select new QuestionResult {q.QuestionId, q.AnswerId};

    return results.ToList();
}