Back to code C#

Ventas por mes con LINQ, sin un solo bucle

Agrupar, ordenar y totalizar una lista de ventas en una sola consulta legible.

This post is not in your language yet; you are seeing it in Spanish. The code is the same.

The problem

Tenés una lista de ventas en memoria y te piden el total y la cantidad de tickets por mes. Con bucles y diccionarios salen treinta líneas; con LINQ, una consulta.

C#
using System;
using System.Linq;

record Venta(DateTime Fecha, string Sucursal, decimal Monto);

class Programa {
    static void Main() {
        var ventas = new[] {
            new Venta(new DateTime(2026, 1, 15), "Centro", 1200m),
            new Venta(new DateTime(2026, 1, 28), "Norte",   800m),
            new Venta(new DateTime(2026, 2, 3),  "Centro", 1500m),
            new Venta(new DateTime(2026, 2, 19), "Centro",  700m),
        };

        var porMes = ventas
            .GroupBy(v => new { v.Fecha.Year, v.Fecha.Month })
            .OrderBy(g => g.Key.Year).ThenBy(g => g.Key.Month)
            .Select(g => new { Mes = $"{g.Key.Year}-{g.Key.Month:00}", Total = g.Sum(v => v.Monto), Tickets = g.Count() });

        foreach (var m in porMes)
            Console.WriteLine($"{m.Mes}: {m.Total,10:N2} en {m.Tickets} ventas");
    }
}

Why it is written this way

  1. GroupBy con un objeto anónimo agrupa por año y mes a la vez: enero de 2026 no se mezcla con enero de 2027.
  2. Cada grupo se comporta como una lista: por eso se le puede pedir Sum y Count.
  3. El dinero va en decimal (el sufijo m), nunca en double: los centavos no admiten redondeo binario.
  4. El formato {m.Total,10:N2} alinea a diez caracteres con dos decimales y separador de miles.
How to try it

dotnet new console -n Ventas, reemplazá Program.cs con este código y corré dotnet run.

Watch out

Sobre una lista en memoria esto es instantáneo. Sobre una base con Entity Framework, la misma consulta se traduce a SQL: revisá el SQL generado antes de confiar en que agrupa en el servidor.

Adapt it to your case with AI

The button copies this prompt with the code pasted below it. Replace the brackets with your own details and paste it into ChatGPT, Claude, Gemini or Copilot.

The prompt
Tengo esta consulta LINQ que agrupa ventas por mes. Extendela para que además agrupe por [SEGUNDA DIMENSIÓN: sucursal, vendedor, categoría], calcule la variación porcentual contra el mes anterior y marque los meses que caen más de [UMBRAL]%. Mis datos vienen de [ORIGEN: lista en memoria, EF Core, CSV]. Mantené decimal para el dinero.

Example written and reviewed by hand.

Share

Comments

No comments yet. Yours can be the first.

Plain text only, no links. No email is requested. Comments are reviewed before they are published.

Did you adapt it to something of yours?

Tell me what you solved with it, or what it was missing.

Keep trying

More code

See all
Darinel Ortega Online · I reply during the day
Today
Hello. I'm not selling anything here: this is for exchanging knowledge about technology.
Write whatever you like — you can send text, images or documents. Messages reach my console and I reply from there.
You are writing outside working hours. I will read you as soon as the day starts.

An open conversation to share knowledge. Messages reach my console and I reply from there.

Let us book a conversation

Pick the day and time that work for you. Thirty minutes, no sales pitch.

Video call

For a video call, just ask for one here and I'll send you the session link.