У меня есть запрос linq, в котором есть предложение Group By, но Group SQL не выполняется на сервере sql.
Я попытался простой запрос, и Group By происходит на сервере SQL.
Пожалуйста, объясните мне, почему это другое поведение?
Я хочу, чтобы эта группа на сервере для улучшения производительности.
Простой запрос, в котором я получаю групповые запросы, если я регистрирую SQL-запрос:
var testt = (from doc in _patientRepository.Documents
group doc by doc.DocumentType into G
select new
{
Key = G.Key
}).ToList();
Сгенерированный sql:
Executed DbCommand (247ms) [Parameters=[], CommandType='Text',
CommandTimeout='30']
SELECT [doc].[DocumentType] AS [Key]
FROM [Document] AS [doc]
GROUP BY [doc].[DocumentType]
Запрос на выдачу:
var patX = (from doc in _patientRepository.Documents
join pat in _patientRepository.Patients
on doc.PatientId.ToString().ToLower() equals pat.PatientId.ToString().ToLower()
where doc.Source.ToLower() != "testclient.server.postman" &&
pat.Deleted == false && sfHCPs.Contains(pat.HcpId.ToLower())
select new Document()
{
DocumentId = doc.DocumentId,
CreationDateTime = doc.CreationDateTime,
DocumentType = doc.DocumentType,
PatientId = doc.PatientId,
DocumentTypeVersion = doc.DocumentTypeVersion,
Source = doc.Source,
PayloadLeft = DocumentMapper.DeserializePayload(doc.PayloadLeft),
PayloadRight = DocumentMapper.DeserializePayload(doc.PayloadRight),
PayloadBoth = DocumentMapper.DeserializePayload(doc.PayloadBoth),
IsSalesforceSynced = doc.IsSalesforceSynced,
HcpId = pat.HcpId
}).GroupBy(p => new { p.PatientId, p.DocumentType })
.Select(g => g.OrderByDescending(p => p.CreationDateTime).FirstOrDefault())
.Where(x => x.IsSalesforceSynced == false)
.ToList();
Почему он не сгенерировал sql для группировки:
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (200ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [doc].[DocumentId], [doc].[CreationDateTime], [doc].[DocumentType], [doc].[PatientId], [doc].[DocumentTypeVersion], [doc].[Source], [doc].[PayloadLeft], [doc].[PayloadRight], [doc].[PayloadBoth], [doc].[IsSalesforceSynced], [pat].[HcpId]
FROM [Document] AS [doc]
INNER JOIN [Patient] AS [pat] ON LOWER(CONVERT(VARCHAR(36), [doc].[PatientId])) = LOWER(CONVERT(VARCHAR(36), [pat].[PatientId]))
WHERE ((LOWER([doc].[Source]) <> N'testclient.server.postman') AND ([pat].[Deleted] = 0)) AND LOWER([pat].[HcpId]) IN (N'4e7103a9-7dff-4fa5-b540-a32a31be2997', N'abc1', N'def2', N'ghi3')
ORDER BY [doc].[PatientId], [doc].[DocumentType]
Я попробовал следующий подход, но сгенерировал тот же SQL:
var patX = ((from doc in _patientRepository.Documents
join pat in _patientRepository.Patients
on doc.PatientId.ToString().ToLower()
equals pat.PatientId.ToString().ToLower()
where doc.Source.ToLower() != "testclient.server.postman" &&
pat.Deleted == false && sfHCPs.Contains(pat.HcpId.ToLower())
select new Document()
{
DocumentId = doc.DocumentId,
CreationDateTime = doc.CreationDateTime,
DocumentType = doc.DocumentType,
PatientId = doc.PatientId,
DocumentTypeVersion = doc.DocumentTypeVersion,
Source = doc.Source,
PayloadLeft = DocumentMapper.DeserializePayload(doc.PayloadLeft),
PayloadRight = DocumentMapper.DeserializePayload(doc.PayloadRight),
PayloadBoth = DocumentMapper.DeserializePayload(doc.PayloadBoth),
IsSalesforceSynced = doc.IsSalesforceSynced,
HcpId = pat.HcpId
}).GroupBy(p => new { p.PatientId, p.DocumentType })
.Select(g => g.OrderByDescending(p => p.CreationDateTime).FirstOrDefault())
.Where(x => x.IsSalesforceSynced == false))
.ToList();