es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

EF Core/SQL Unir una entidad diferente según una condición.

Supongamos que tengo una tabla llamada Transacciones

Transacciones tiene las siguientes columnas:

OrderId,
OrderType (puede ser 0 = Venta o 1 = Compra),
Amount

Ahora quiero obtener los datos relevantes basados en el OrderType. Si OrderType = 0, entonces unir con Sale Table, de lo contrario unir con Purchase Table.

Actualmente, lo que estoy haciendo es hacer tres llamadas a la base de datos para obtener algunos otros valores de otras tablas (lo cual funciona, pero es altamente ineficiente a largo plazo, ya que 3 llamadas son malas en cuanto a rendimiento).

Mi solución es usar un join con SQL izquierdo.

SELECT ap.*, coalesce(s.orderNo,p.orderNo) as orderNo
FROM apptransactions AS ap
LEFT JOIN sales AS s ON (ap.orderType = 0 and ap.orderId = s.id)
LEFT JOIN purchases AS p ON (ap.orderType = 1 and ap.orderId = p.id);

¿Cómo se puede convertir esta consulta a EF Core?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para convertir la consulta SQL a EF Core puedes usar LINQ to Entities. Aquí tienes un ejemplo:

    Suponiendo que tienes modelos para Transacciones, Ventas y Compras:

    public class Transaction
    {
        public int OrderId { get; set; }
        public int OrderType { get; set; }
        public decimal Amount { get; set; }
    }
    
    public class Sale
    {
        public int Id { get; set; }
        public string OrderNo { get; set; }
    }
    
    public class Purchase
    {
        public int Id { get; set; }
        public string OrderNo { get; set; }
    }
    

    Entonces, en tu DbContext, tendrías:

    public DbSet<transaction> Transactions { get; set; }
    public DbSet<sale> Sales { get; set; }
    public DbSet<purchase> Purchases { get; set; }
    

    Y puedes usar LINQ to Entities para escribir una consulta que une la tabla Transactions con la tabla Sales o Purchases según el OrderType:

    var result = from t in Transactions
                 join s in Sales on t.OrderId equals s.Id into sGroup
                 from s in sGroup.DefaultIfEmpty()
                 join p in Purchases on t.OrderId equals p.Id into pGroup
                 from p in pGroup.DefaultIfEmpty()
                 select new
                 {
                     t.OrderId,
                     t.OrderType,
                     t.Amount,
                     OrderNo = t.OrderType == 0 ? s.OrderNo : p.OrderNo
                 };
    

    Esta consulta LINQ generará SQL similar a la consulta SQL que proporcionaste, usando left joins para unir la tabla Transactions con la tabla Sales o Purchases según el OrderType. La función coalesce se reemplaza con un operador ternario que verifica el OrderType para determinar qué OrderNo usar.

Comments are closed.