【发布时间】:2019-11-09 16:03:39
【问题描述】:
我有一个包含 Group By 子句的 linq 查询,但 Group By 没有在 sql server 上发生。 我尝试了一个简单的查询,并且 Group By 发生在 sql server 上。 请指导我为什么会有这种不同的行为? 我希望在服务器上进行分组以提高性能。
如果我记录 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();
为什么不生成group-by 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();
【问题讨论】:
-
我认为你的问题可能是你的
select在中间。你应该最后做select。 -
第一次选择和分组依据创建组,第二次选择从每个组中获取最新数据。
-
我不能先分组。我的流程是这样的:选择文档 > 按某些条件对它们进行分组 > 获取每个组的第一个成员。
-
为什么不能先分组?
标签: entity-framework linq-to-sql entity-framework-core linq-to-entities entity-framework-core-2.1