繁体   English   中英

LINQ:在分组后从实体的集合中选择最小值和最大值

[英]LINQ: Select the Min and Max values from a collection on an entity after grouping

目标是从实体(外键)上的集合中获取第一个DateTime和Last DateTime。 我的实体是一个组织,我的收藏是发票。 我正在对结果进行分组,因为很遗憾,组织并不是唯一的。 我正在处理重复数据,并且不能假设我的组织是唯一的,所以我在我的实体上按数字字段进行分组。

我正在使用.NET Core 2.1.2和Entity Framework。

我正在尝试从LINQ生成以下查询:

SELECT MIN([organization].[Id]) AS Id, MIN([organization].[Name]) AS Name, 
MIN([organization].[Number]) AS Number, MIN([invoice].[Date]) 
AS First, MAX([invoice].[Date]) AS Last
FROM [organization]
INNER JOIN [invoice] ON [invoice].[OrganizationId] = [organization].[Id]
GROUP BY [organization].[Number], [organization].[Name]
ORDER BY [organization].[Name]

但是我不知道如何编写LINQ查询以使其生成此结果。

我得到了:

await _context
            .Organization
            .Where(z => z.Invoices.Any())
            .GroupBy(organization => new
            {
                organization.Number,
                organization.Name
            })
            .Select(grouping => new
            {
                Id = grouping.Min(organization => organization.Id),
                Name = grouping.Min(organization => organization.Name),
                Number= grouping.Min(organization => organization.Number),
                //First = ?,
                //Last = ?
            })
            .OrderBy(z => z.Name)
            .ToListAsync();

我不知道如何编写LINQ查询,以便生成上述内容。

我还有几个问题:

  • Id,Name和Number的Min语句是否正确获取分组中第一个元素的方法?
  • 我是否需要连接语句或“更好地存在”(这是在我更改代码之前生成的)?

有谁知道如何完成LINQ语句的编写? 因为我必须从我的组织实体的发票集合中获取第一个和最后一个日期:

organization.Invoices.Min(invoice => invoice.Date)
organization.Invoices.Max(invoice => invoice.Date)

这是诀窍。

要使用集合导航属性进行inner join ,请使用SelectMany并投影稍后需要的所有基本属性(这对于当前的EF Core查询转换器很重要)。 然后执行GroupBy并投影关键属性/聚合。 最后做订购。

所以

var query = _context
    .Organization
    .SelectMany(organization => organization.Invoices, (organization, invoice) => new
    {
        organization.Id,
        organization.Number,
        organization.Name,
        invoice.Date
    })
    .GroupBy(e => new
    {
        e.Number,
        e.Name
    })
    .Select(g => new
    {
        Id = g.Min(e => e.Id),
        Name = g.Key.Name,
        Number = g.Key.Number,
        First = g.Min(e => e.Date),
        Last = g.Max(e => e.Date),
    })
    .OrderBy(e => e.Name);

被翻译成

SELECT MIN([organization].[Id]) AS [Id], [organization].[Name], [organization].[Number], 
    MIN([organization.Invoice].[Date]) AS [First], MAX([organization.Invoice].[Date]) AS [Last]
FROM [Organization] AS [organization]
INNER JOIN [Invoice] AS [organization.Invoice] ON [organization].[Id] = [organization.Invoice].[OrganizationId]
GROUP BY [organization].[Number], [organization].[Name]
ORDER BY [organization].[Name]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM