c# - LINQ:分组后从实体集合中选择最小值和最大值

标签 c# linq .net-core entity-framework-core

目标是从实体(外键)的集合中获取第一个 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 语句是否是获取 分组中的第一个元素?
  • 我需要连接语句还是“WHERE EXISTS”更好(这是在我更改代码之前生成的)?

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

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

最佳答案

这是诀窍。

要通过使用集合导航属性进行内部连接,只需使用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]

关于c# - LINQ:分组后从实体集合中选择最小值和最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51790044/

相关文章:

c# - 导致错误的阶乘方法

c# - 我正在尝试使用 linq 简化一个语句,该语句采用 2 个数字列表并从第二个数字中减去第一个数字

c# - 消除一条线不在附近的区域

Azure Batch 服务 - 找不到 appsettings.json

.net-core - AddHttpClient 配置的 HttpClient.Timeout 被忽略

c# - dotnet 核心 webapi json-api 兼容查询字符串路由

c# - 捕获 ASP.NET Core MVC 中的异常

c# - 我如何将此linq代码转换为嵌入式SQL

c# - 调试进程的转储代码

c# - 如何使用查询语法来创建排列?