Возврат из ядра Entity Framework

#performance #linq #entity-framework-core #query-optimization

#Производительность #linq #entity-framework-core #оптимизация запросов

Вопрос:

У меня есть этот метод, который возвращает данные из моей базы данных:

 public IList<Questions> GetAllQuestions(string orgId)
    {
        IList<Questions> questions = new List<Questions>();
        var x = (from o in _context.OrganizationProducts
                     join t in _context.Trackers on o.OrganizationId equals t.OrganizationId
                     join tq in _context.TrackerQuestions on t.TrackerId equals tq.TrackerId
                     join tra in _context.TrackerResponseAnswers on tq.TrackerQuestionId equals tra.TrackerQuestionId
                     join tqc in _context.TrackerQuestionChoices on tq.TrackerQuestionId equals tqc.TrackerQuestionId
                     join tr in _context.TrackerResponseAnswers on tq.TrackerQuestionId equals tr.TrackerQuestionId
                     where o.Organization.Name == orgId
                     
                     orderby tq.SortOrder
                     
                     select new
                     {
                         o.OrganizationId,
                         t.Name,
                         tq.QuestionText,
                         tqc.DisplayValue,
                         tqc.Value,
                         tqc.SortOrder,
                         tq.InputType
                     }).Distinct();
        foreach(var record in x)
        {
            questions.Add(new Questions { DisplayValue = record.DisplayValue, 
                                          InputType = record.InputType, 
                                          Name = record.Name, 
                                          OrganizationId = record.OrganizationId, 
                                          QuestionText = record.QuestionText, 
                                          SortOrder = record.SortOrder, 
                                          Value = record.Value });
        }
        return questions;
    }
 

С соответствующим классом вопросов:

 public class Questions
{
    public Guid OrganizationId { get; set; }
    public string Name { get; set; }
    public string QuestionText { get; set; }
    public string DisplayValue { get; set; }
    public string Value { get; set; }
    public int SortOrder { get; set; }
    public string InputType { get; set; }
}
 

Вот ответ, который я получаю от этого класса (некоторая информация удалена для безопасности):

  {
    "organizationId": "[ID]",
    "name": "Quiz 1",
    "questionText": "Are you and your romantic partner:",
    "displayValue": "Dating",
    "value": "Dating",
    "sortOrder": 1,
    "inputType": "radio"
},
{
    "organizationId": "[ID]",
    "name": "Quiz 1",
    "questionText": "Are you and your romantic partner:",
    "displayValue": "Engaged",
    "value": "Engaged",
    "sortOrder": 2,
    "inputType": "radio"
},
{
    "organizationId": "[ID]",
    "name": "Quiz 1",
    "questionText": "Are you and your romantic partner:",
    "displayValue": "Married",
    "value": "Married",
    "sortOrder": 3,
    "inputType": "radio"
},
 

Я хотел бы, чтобы это было больше похоже на это:

 {
    "organizationId": "[ID]",
    "name": "Quiz 1",
    "questionText": "Are you and your romantic partner:",
    "displayValue": ["Engaged", "Married", "Dating"],
    "value": ["Engaged", "Married", "Dating"],
   
    "inputType": "radio"
},
 

Или еще лучше это:

 {
        "organizationId": "[ID]",
        "name": "Quiz 1",
        "questionText": "Are you and your romantic partner:",
        "Answers": [
                  {
                     "DiplayValue": "Dating",
                     "value": "Dating",
                     "sortOrder": 1
                  },
                  {
                     "DiplayValue": "Engaged",
                     "value": "Engaged",
                     "sortOrder": 2
                  },
                  {
                     "DiplayValue": "Married",
                     "value": "Married",
                     "sortOrder": 2
                  },
         ],
        "inputType": "radio"
    },
 

Итак, я попытался сгруппировать вопросы следующим образом:

 var groupQuestions = questions.Where(x => x.QuestionText != null).GroupBy(x => new { x.QuestionText, x.Value }).Select(g => g.ToList()).ToList();
 

Но он по-прежнему не выводит его. Как это делается? Кроме того, этот запрос выполняется немного медленно, есть предложения по улучшению производительности?

Ответ №1:

На самом деле нет чего-то особенного. Но группировка должна быть предоставлена на стороне клиента.

 public IList<Questions> GetAllQuestions(string orgId)
{
    var query = from o in _context.OrganizationProducts
                join t in _context.Trackers on o.OrganizationId equals t.OrganizationId
                join tq in _context.TrackerQuestions on t.TrackerId equals tq.TrackerId
                join tra in _context.TrackerResponseAnswers on tq.TrackerQuestionId equals tra.TrackerQuestionId
                join tqc in _context.TrackerQuestionChoices on tq.TrackerQuestionId equals tqc.TrackerQuestionId
                join tr in _context.TrackerResponseAnswers on tq.TrackerQuestionId equals tr.TrackerQuestionId
                where o.Organization.Name == orgId
                orderby tq.SortOrder
                select new
                {
                    o.OrganizationId,
                    t.Name,
                    tq.QuestionText,
                    tqc.DisplayValue,
                    tqc.Value,
                    tqc.SortOrder,
                    tq.InputType
                };

    var enumerable = query.Distinct().AsEnumerable();

    var questionsQuery = 
       from q in enumerable
       group q by new { q.OrganizationId, q.Name, q.QuestionText, q.InputType } into g
       select new Questions
       {
           organizationId = g.Key.OrganizationId,
           name = g.Key.name,
           questionText = g.Key.QuestionText,
           Answers = g.OrderBy(a => a.SortOrder).Select(a => new Answer
           {
              DiplayValue = a.DiplayValue,
              value = a.Value,
              sortOrder = a.SortOrder
           }).ToArray()

           inputType = g.Key.InputType
       }

   var questions = questionsQuery.ToList();

}