【问题标题】:Optimise linq to sql query with subselect to get latest result使用 subselect 优化 linq to sql 查询以获得最新结果
【发布时间】:2010-12-29 23:36:11
【问题描述】:

我将测验的结果存储在表格中,我需要找出用户特定测验的所有问题的最新答案 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,如果您需要更多详细信息,请告诉我。

谢谢,

安妮莉

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

    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.QuestionId 第一个q 超出范围之后,这个名称可能会再次使用。

    【讨论】:

    • 谢谢,这真的很简洁!必须对其进行投射才能正常工作,否则可以享受美食。
    【解决方案2】:

    这就是我将如何攻击它。第一个查询将给出用户参加测验的最近时间。第二个查询将获得该测验的结果,并选择到 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();
    } 
    

    【讨论】:

    • 感谢您的回答!我确实喜欢为了可读性而将事情分开,尽管我非常喜欢 Mykola 答案中的分组,所以这次选择了那个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    相关资源
    最近更新 更多