¿Cómo puedo encontrar la ciudad donde el número de producto x es más ordenado en una consulta Linq?

Mis estructuras de clase son las siguientes;

public class Users
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int CityId { get; set; }
}
public class Order
{
    public int Id { get; set; }
    public int UserId { get; set; }
}

public class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Amount { get; set; }
}

La consulta que quiero escribir como Linq es la siguiente:

select * from
(select u.CityId, sum(od.Amount),
        ROW_NUMBER() over(order by sum(od.Amount) desc) as rn
    from Order o
        inner join OrderDetail od on o.Id = od.OrderId
        inner join Users u on u.Id = o.UserId
    where od.ProductId = x
    group by u.CityId
) 
where rn = 1;

He probado muchas cosas, pero no pude ajustarme a la estructura. Gracias por ahora.

Pregunta hecha hace 3 años, 4 meses, 28 días - Por bytebison


4 Respuestas:

  • Aparentemente tienes una mesa Cities con una relación de uno a hombre Users: Cada Ciudad tiene cero o más Usuarios, cada Usuario vive exactamente en una Ciudad, a saber, la Ciudad que la llave extranjera User.CityId se refiere.

    Análogamente, existe una relación de uno a hombre entre Users y Orders: Cada Usuario ha colocado cero o más Pedidos, cada Orden ha sido colocado por un Usuario exactamente, a saber, el Usuario que la llave extranjera Order.UserId se refiere.

    Otras dos relaciones entre sí: Orders y OrderDetails y Products y OrderDetails: cada producto es un producto en cero o más detalles de pedidos. Cada PedidoDetail es exactamente sobre un Producto, a saber, el Producto al que se refiere ProductId clave extranjera.

    ¿Cómo puedo encontrar la ciudad donde el número de producto x es más ordenado en una consulta Linq?

    Usted no está interesado en Usuarios, Pedidos, Detalles de Pedido, ni siquiera interesado en todos los Productos, sólo en el Producto X. Y usted quiere la ciudad donde este producto X está más ordenado.

    Para ello, necesitas unirte a Ciudades - Usuarios - Pedidos - OrdenarDetalles, y mantener solo combinaciones de [Ciudad; OrdenDetalle. Cantidad; Producto. Id.

    Quitar todas las combinaciones que no se trata de "Número de producto X". Las combinaciones restantes son todo sobre el producto X. GroupBy City, y Sum todas las Cantidades de todas las PedidasDetalles de esta Ciudad.

    Orden Por Descending Sum, y mantener el primero.

    ¡Esto va a ser un gran LINQ! Por suerte no es muy difícil.

    Primero nos unimos para hacer las combinaciones [City, User, Order, OrderDetails], y conservamos solamente las propiedades que necesitamos: [City, Amount, ProductId]

    var productNumberX = ...;
    var result = dbContext.Cities.Join(dbContext.Users,   // inner join Cities and Users
    city => city.Id,                               // from every city take the primary key
    user => user.CityId,                           // from every user take the foreign key
    
    (city, user) => new                            // when they match, make one new
    {
        City = city,
        UserId = user.Id,                     // for the next join we only need the UserId
    })
    

    Continúe el LINQ con la segunda unión: únase con las ordenes:

    .Join(dbContext.Orders,
    previousJoinResult => previousJoinResult.UserId,  // from previous join take the UserId
    order => order.UserId,                            // from the Order take the UserId
    
    (previousJoinResult, order) => new                // when they match, make one new
    {
        City = previousJoinResult.City,
        OrderId = order.Id,                  // for the next Join we only need the OrderId
    })
    

    3a sesión: con los detalles de la orden. Recuerde la cantidad y la propiedad.

    .Join(dbContext.OrderDetails,
    previousJoinResult => previousJoinResult.OrderId,   // get the OrderId from previous join
    orderDetail => orderDetail.OrderId,                 // get foreign key OrderId
    
    (previousJoinResult, orderDetail) => new
    {
        City = previousJoinResult.City,
        Amount = orderDetail.Amount,
        ProductId = orderDetail.ProductId,
    })
    

    Mantenga solamente [City, Amount, ProductId] combinaciones que son sobre "Product number X":

    .Where(joinResult => joinResult.ProductId == productNumberX)
    

    Phew, así que ahora tenemos combinaciones [City, Amount, ProductId] de todo el productoNumberX. Haz grupos de la misma ciudad. Usar el sobrecarga de Queryable. GroupBy que tiene elemento de parámetrosSelector y resultadoSelector.

    Entonces:
    KeySelector: grupos de la misma ciudad;
    ElementSelector: sólo la cantidad de todas las combinaciones de ensamblados;
    ResultadoSelector: cada ciudad con la suma de sus cantidades

    No necesitamos al ProductId, todos son iguales.

    .GroupBy(joinResult => joinResult.City,
    
    // elementSelector: keep only the Amount of the JoinResult
    joinResult => joinResult.Amount,
    
    // parameter resultSelector: for every City, and all Amounts of orderDetails of Orders
    // that were placed by Users in this City, make one new
    // containing the City and the sum of the amounts
    (city, amountsInThisCity) => new
    {
        City = city,
        TotalAmount = amountsInThisCity.Sum(),
    })
    

    Por lo tanto, para cada Ciudad, que tenía al menos un Usuario que puso una Orden que tenía una OrdenDetalle del Producto X, ahora tienes la suma de las Cantidades de todos los PedidosDetalles del producto X de todas las Pedidos de todos los Usuarios en la ciudad.

    Ordenar por Descendiendo TotalAmount, y tomar el primero:

    .OrderByDescending(city => city.TotalAmount)
    .FirstOrDefault();
    

    Resultado:

    la ciudad donde el número de producto x es más ordenado, o nulo si nadie ha pedido el número de producto X.

    Respondida el Dec 19, 2020 a las 13:52 - por techscribe

    Votos positivos: 0 | Votos negativos: 0

  • Pruebe lo siguiente:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Context db = new Context();
                int productId = 123;
                var results = (from u in db.Users
                               join o in db.Order on u.Id equals o.UserId
                               join od in db.OrderDetails.Where(x => x.ProductId == productId) on o.Id equals od.OrderId
                               select new { u = u, o = o, od = od }
                               ).GroupBy(x => x.u.CityId)
                               .Select(x => new { city = x.Key, sum = x.Sum(y => y.od.Amount) })
                               .OrderByDescending(x => x.sum)
                               .ToList();
            }
        }
        public class Context
        {
            public List Users { get;set;}
            public List Order { get; set; }
            public List OrderDetails { get; set; }
        }
        public class Users
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Surname { get; set; }
            public int CityId { get; set; }
        }
        public class Order
        {
            public int Id { get; set; }
            public int UserId { get; set; }
        }
    
        public class OrderDetail
        {
            public int Id { get; set; }
            public int OrderId { get; set; }
            public int ProductId { get; set; }
            public int Amount { get; set; }
        }
    }
    

    Respondida el Dec 19, 2020 a las 14:02 - por codecraftsman32c9

    Votos positivos: 0 | Votos negativos: 0

  • Para traducir tu consulta SQL a una consulta LINQ en C

    , primero necesitas mapear tus clases a entidades de Entity Framework para poder realizar las consultas. Asumiendo que tengas una DbContext con DbSet para cada una de tus entidades, aquí te muestro cómo podrías hacer la consulta que buscas:

    csharp
    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    public class CityOrder
    {
        public int CityId { get; set; }
        public int TotalAmount { get; set; }
    }
    
    public class Program
    {
        public static void Main()
        {
            int x = 123; // Aquí debes especificar el ID del producto que estás buscando
    
            using (var context = new YourDbContext())
            {
                var cityOrders = context.Orders
                    .Where(o => o.OrderDetails.Any(od => od.ProductId == x))
                    .GroupBy(o => o.User.CityId)
                    .Select(g => new CityOrder
                    {
                        CityId = g.Key,
                        TotalAmount = g.Sum(o => o.OrderDetails.Where(od => od.ProductId == x).Sum(od => od.Amount))
                    })
                    .OrderByDescending(co => co.TotalAmount)
                    .FirstOrDefault();
    
                if (cityOrders != null)
                {
                    // cityOrders.CityId contiene el ID de la ciudad más ordenada para el producto x
                    Console.WriteLine("Ciudad con ID {0} es la más ordenada para el producto {1}", cityOrders.CityId, x);
                }
                else
                {
                    Console.WriteLine("No se encontraron resultados para el producto {0}", x);
                }
            }
        }
    }
    

    En este ejemplo, asumimos que tienes las relaciones entre las entidades configuradas correctamente en tu contexto de Entity Framework. La consulta LINQ realiza la agrupación por ciudad, calcula la suma total de la cantidad de un producto determinado por ciudad, ordena los resultados por la cantidad total en orden descendente y luego selecciona la ciudad con la mayor cantidad.

    Respondida el Dec 20, 2020 a las 13:51 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Claro Aquí tienes cómo puedes escribir esa consulta utilizando LINQ: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad, CantidadOrden) mediante Join/GroupBy 2. Clasifica según CantidadOrden descendentemente 3. Toma sólo primeras ocurrencia(s) según cantidad orden: 1. Obtén pares clave-valor ​​(Ciudad,

    Respondida el Dec 20, 2020 a las 13:58 - por Gemini

    Votos positivos: 0 | Votos negativos: 0