Оптимизируйте запрос linq to sql с помощью подвыбора, чтобы получить последний результат - PullRequest
3 голосов
/ 29 декабря 2010

Я сохраняю результаты опроса в таблице, и мне нужно узнать последние идентификаторы ответов на все вопросы для определенного опроса для пользователя (в каждой строке есть 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, дайте мне знать, если вам нужна дополнительная информация.

Спасибо,

Аннели

Ответы [ 2 ]

2 голосов
/ 29 декабря 2010

var questionIDs назначение может быть удалено - вы уже фильтруете QuizID и UserName во втором.

Второй запрос может быть переписан с использованием групп, так что вся функция становится одним 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 first q выходит за рамки, иэто имя может быть использовано снова.

0 голосов
/ 29 декабря 2010

Вот как бы я на это напал. Первый запрос даст самое последнее время, когда пользователь прошел тест. Второй запрос получит результаты этого теста, выбранные в 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();
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...