2010-12-29 3 views
3

퀴즈 결과를 테이블에 저장하고 있으며 사용자의 특정 퀴즈에 대한 모든 질문에 최신 답변 ID를 찾아야합니다 (각 행에는 id, quizid, questionid, answerid, username 및 datecompleted).최신 결과를 얻으려면 subselect를 사용하여 linq를 subselect로 최적화하십시오.

나는 그것을 만들었지 만 너무 못생긴 생각으로 나는 그것을 최적화 할 도움을 요청했다. 나는 새로운 해를 일찍 시작하고, 더 나은 품질의 코드를 작성한다. :) 그래서 만약 누군가가 크게 나를 평가할 수있는 그것을 최적화하는 방법을 말하는 느낌!

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

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 범위를 벗어났습니다.이 이름을 다시 사용할 수 있습니다.

+0

감사합니다. 이것은 정말 훌륭하고 간결합니다! 그것이 그것을 위해 그것을 던져야했다, 그렇지 않으면 대접을 움직이게한다. – annelie

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(); 
} 
+0

답변 해 주셔서 감사합니다. 비록 Mykola의 답변에서 그룹화가 너무 좋았지 만 이번에는 그 중 하나를 골랐다. – annelie

관련 문제