2017-03-10 11 views
-1

私はコンパイルされたクエリにそのような複雑なクエリをどのように変換し、コードをきれいに保つことができるかを理解しようとしています。これは複雑ではありませんが、私はもっと複雑なクエリを持っています。複雑なlinqのコンパイルされたクエリ

だから私は、この投影クエリ変換したい:

public List<Answer> GetAnswers(int pQuestionId, string pSearch, int?  pSkip, int? pTake, GetAnswersOrderBy pOrderBy, bool pOrderByIsAscending, out int pTotalNumberOfLines) 
{ 
    var compiledQuery = CompiledGetAnswers(params...); 

    var projectedQuery = compiledQuery .Select(s => 
     new 
     { 
      Answer = s, 
      s.AnswerTranslations, 
      AnswerTranslationsLanguages = s.AnswerTranslations.Select(qt => qt.Language), 
     }).ToList(); 

    return projectedQuery.Select(s => new GetAnswers() 
    { 
     Id = s.Answer.Id, 
     Label = s.Answer.Label, 
     CorrectAnswer = s.Answer.CorrectAnswer, 
     Feedback = s.Answer.Feedback, 
     Weighting = s.Answer.Weighting 
    }).ToList(); 
} 

public static Func<AppDbContext, Answer, IQueryable<Answer>> CompiledGetAnswers(int pQuestionId, string pSearch, int?  pSkip, int? pTake, GetAnswersOrderBy pOrderBy, bool pOrderByIsAscending, out int pTotalNumberOfLines) 
{ 
    string search = pSearch.ToUpper().Replace(" ", ""); 
    string languageCode = Thread.CurrentThread.CurrentCulture.ToString().ToLower().Substring(0, 2); 
    IQueryable<Answer> query = this.Context.Set<Answer>(); 
    //Filter question by questionnaire 
    query = query.Where(w => w.QuestionID == pQuestionId); 

    if (!string.IsNullOrEmpty(pSearch)) 
     query = query.Where(w => (w.AnswerTranslations.Any(a => languageCode == a.LanguageCode) 
         ? w.AnswerTranslations.FirstOrDefault(a => languageCode == a.LanguageCode).Label 
         : w.AnswerTranslations.OrderBy(o => o.Language.Priority).FirstOrDefault().Label) 
         .ToUpper().Replace(" ", "") 
         .Contains(search)); 
    switch (pOrderBy) 
    { 
     case GetAnswersOrderBy.CorrectAnswer: 
      query = pOrderByIsAscending ? query.OrderBy(w => w.CorrectAnswer) : query.OrderByDescending(w => w.CorrectAnswer); 
      break; 
     case GetAnswersOrderBy.ResponseCount: 
      query = pOrderByIsAscending ? query.OrderBy(w => w.ResponseCount) : query.OrderByDescending(w => w.ResponseCount); 
      break; 
     default: 
      break; 
    } 
    pTotalNumberOfLines = query.Count(); 

    var pagedQuery = query.Skip(pSkip ?? 0) 
         .Take(pTake ?? pTotalNumberOfLines); 
    return CompiledQuery(AppDbContext db, Answer a) => pagedQuery; 
} 
+0

あなたはほとんどそれをやっています。 –

答えて

0

私はあなたがきれいでどのような意味を推測は「読みやすく」です:きれいなコードを維持するために、このような何かに

public List<GetAnswers> GetAnswers(int pQuestionId, string pSearch, int?  pSkip, int? pTake, GetAnswersOrderBy pOrderBy, bool pOrderByIsAscending, out int pTotalNumberOfLines) 
{ 
    string search = pSearch.ToUpper().Replace(" ", ""); 
    string languageCode = Thread.CurrentThread.CurrentCulture.ToString().ToLower().Substring(0, 2); 
    IQueryable<Answer> query = this.Context.Set<Answer>(); 
    //Filter question by questionnaire 
    query = query.Where(w => w.QuestionID == pQuestionId); 

    if (!string.IsNullOrEmpty(pSearch)) 
     query = query.Where(w => (w.AnswerTranslations.Any(a => languageCode == a.LanguageCode) 
         ? w.AnswerTranslations.FirstOrDefault(a => languageCode == a.LanguageCode).Label 
         : w.AnswerTranslations.OrderBy(o => o.Language.Priority).FirstOrDefault().Label) 
         .ToUpper().Replace(" ", "") 
         .Contains(search)); 
    switch (pOrderBy) 
    { 
     case GetAnswersOrderBy.CorrectAnswer: 
      query = pOrderByIsAscending ? query.OrderBy(w => w.CorrectAnswer) : query.OrderByDescending(w => w.CorrectAnswer); 
      break; 
     case GetAnswersOrderBy.ResponseCount: 
      query = pOrderByIsAscending ? query.OrderBy(w => w.ResponseCount) : query.OrderByDescending(w => w.ResponseCount); 
      break; 
     default: 
      break; 
    } 
    pTotalNumberOfLines = query.Count(); 

    var pagedQuery = query.Skip(pSkip ?? 0) 
         .Take(pTake ?? pTotalNumberOfLines); 
    var projectedQuery = pagedQuery.Select(s => 
     new 
     { 
      Answer = s, 
      s.AnswerTranslations, 
      AnswerTranslationsLanguages = s.AnswerTranslations.Select(qt => qt.Language), 
     }).ToList(); 
    return projectedQuery.Select(s => new GetAnswers() 
    { 
     Id = s.Answer.Id, 
     Label = s.Answer.Label, 
     CorrectAnswer = s.Answer.CorrectAnswer, 
     Feedback = s.Answer.Feedback, 
     Weighting = s.Answer.Weighting 
    }).ToList(); 
} 

を。あなたは実際にそれをやっています。私の提案は、あなたの複雑なクエリをメソッドに入れて意味のある名前を付けることです。人々があなたのクエリに見ていない場合たとえば、彼らはあなたが次のコード

query = query.Where(w => (w.AnswerTranslations.Any(a => languageCode == a.LanguageCode) 
         ? w.AnswerTranslations.FirstOrDefault(a => languageCode == a.LanguageCode).Label 
         : w.AnswerTranslations.OrderBy(o => o.Language.Priority).FirstOrDefault().Label) 
         .ToUpper().Replace(" ", "") 
         .Contains(search)); 

で何をしている

を理解することはありませんあなたは

public static class MyQueryExtension 
{ 
    public static IQueryable<Answer> SearchAnswersByLanguageCode(this IQueryable<Answer> query, string languageCode, string search) 
    { 
     return query.Where(w => (w.AnswerTranslations.Any(a => languageCode == a.LanguageCode) 
        ? w.AnswerTranslations.FirstOrDefault(a => languageCode == a.LanguageCode).Label 
        : w.AnswerTranslations.OrderBy(o => o.Language.Priority).FirstOrDefault().Label) 
        .ToUpper().Replace(" ", "") 
         .Contains(search)) 
    } 
} 

拡張クラスを作ることができますそして、あなたのコード内で

query = query.SearchAnswersByLanguageCode(languageCode, search); 

それを呼び出す次に、あなたのmainメソッドがきれいで読みやすくすることができます

public static Func<AppDbContext, Answer, IQueryable<Answer>> CompiledGetAnswers(int pQuestionId, string pSearch, int?  pSkip, int? pTake, GetAnswersOrderBy pOrderBy, bool pOrderByIsAscending, out int pTotalNumberOfLines) 
{ 
    //Do something 
    if (!string.IsNullOrEmpty(pSearch)) 
     query = query.SearchAnswersByLanguageCode(languageCode, search); 

    query = query.GetItOrdered(parameters); 

    //Do something 
}