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