L'obiettivo è ottenere il primo DateTime e Last DateTime da una raccolta su un'entità (chiave esterna). La mia entità è un'organizzazione e la mia collezione è fatture. Sto raggruppando i risultati poiché le organizzazioni purtroppo non sono uniche. Ho a che fare con dati duplicati e non posso pensare che le mie organizzazioni siano uniche, quindi sto raggruppando per un campo Numero sulla mia Entità.
Sto usando .NET Core 2.1.2 con Entity Framework.
Sto cercando di ottenere la seguente query generata da 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]
Tuttavia non ho idea di come arrivare a scrivere la query LINQ per farlo generare questo risultato.
Sono arrivato fino a:
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();
Non ho idea di come scrivere la query LINQ in modo tale da generare quanto sopra.
Ho ancora un paio di domande:
Qualcuno sa come finire di scrivere la dichiarazione LINQ? Perché devo ottenere la prima e l'ultima data dalla raccolta fatture sulla mia entità organizzativa:
organization.Invoices.Min(invoice => invoice.Date)
organization.Invoices.Max(invoice => invoice.Date)
Ecco il trucco.
Per rendere inner join
utilizzando la proprietà di navigazione insieme, usa SelectMany
e proietta tutte le proprietà primitive di cui hai bisogno in seguito (questo è importante per l'attuale traduttore di query EF Core). Quindi eseguire il GroupBy
e proiettare le proprietà chiave / aggregati. Finalmente fai l'ordine.
Così
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);
è tradotto a
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]