Translate an SQL query to LINQ

7

I am very new using LINQ and I have done few things, right now I have an SQL query that I must implement in LINQ and I have no idea how it is done.

SELECT Boletas.Boleta, DATEPART(DW, CAST(Boletas.Fecha AS datetime)) AS DiaDeLaSemana, 
       Materiales.Descripcion, Clientes.Nombre, 
       induscomer.NoCliente AS induscomerNoCliente
FROM   Boletas 
       INNER JOIN Materiales 
       ON Boletas.Material = Materiales.Material AND Boletas.Familia = Materiales.Familia 
       INNER JOIN Clientes 
       ON Boletas.NoCliente = Clientes.NoCliente 
       LEFT OUTER JOIN induscomer 
       ON Clientes.NoCliente = induscomer.NoCliente
WHERE  (Boletas.Fecha >= '20170101') AND (Boletas.Fecha <= '20170107') 
       AND (Boletas.Status = 'A')
ORDER BY Boletas.Material

So that if the corresponding client does not exist in the table induscomer , then induscomerNoCliente would be null.

I tried following some aids that I found to do so:

var boletaQuery = (
    from b in _context.Boletas
    join m in _context.Materiales on b.Material equals m.Material
    join c in _context.Clientes on b.NoCliente equals c.NoCliente
    join i in _context.induscomer on c.NoCliente equals i.NoCliente into indus
    from ind in indus.DefaultIfEmpty()
    where b.Fecha.CompareTo(FechaIni) >= 0
        && b.Fecha.CompareTo(FechaFin) <= 0
        && b.Status.Equals('A')
    select new { 
        b, 
        induscomerNoCliente = ind.NoCliente, 
        NombreCliente = c.Nombre, 
        DescripcionMaterial = m.Descripcion 
    }
);

But when doing boletaQuery.ToList(); it marks me the following error:

  

Unhandled exception of type 'System.NotSupportedException' in System.Data.Entity.dll   Additional information: A constant value of type 'System.Object' could not be created. Only primitive types or enumeration types are supported in this context.

    
asked by Cyndy 28.03.2017 в 19:58
source

4 answers

4

Well thank you very much everyone for your contributions, following the advice of @ YanetSilvaFernández, @WeimarYamitMorenoPerez, @Flxtr and after a lot of tests the LEFT OUTER JOIN has already been:

 var boletaQuery =
        from b in _context.Boletas
        join m in _context.Materiales 
        on new { k1 = (int?)b.Familia, k2 = (int?)b.Material } 
        equals new { k1 = (int?)m.Familia, k2 = (int?)m.Material }
        join c in _context.Clientes on b.NoCliente equals c.NoCliente
        join i in _context.induscomer on c.NoCliente equals i.NoCliente into indus
        from ind in indus.DefaultIfEmpty()
        where b.Fecha.CompareTo(FechaIni) >= 0 && b.Fecha.CompareTo(FechaFin) <= 0 
        && b.Status.Equals("A")
        select new
        {
            b,
            DiaDeLaSemana = SqlFunctions.DatePart("DW", b.Fecha),
            DescripcionMaterial = m.Descripcion,
            NombreCliente = c.Nombre,
            ind
        };

Then I upload the data to my structure where I defined the field induscomerNoCliente as int? (that allows null) with the following cycle:

        int? indusnocliente;
        foreach (var item in boletaQuery.ToList())
        {
            if (item.ind == null)
            {
                indusnocliente = null;
            }
            else
            {
                indusnocliente = item.ind.NoCliente;
            }
            lsOperacion.Add(new OperacionCL
            {
                Base = item.b.Base,
                Boleta = item.b.Boleta,
                Fecha = item.b.Fecha,
                Contado = (float)item.b.Contado.Value,
                Credito = (float)item.b.Credito.Value,
                Material = (int)item.b.Material.Value,
                Neto = (float)item.b.Neto.Value,
                Total = (float)item.b.Total.Value,
                NombreCliente = item.NombreCliente,
                DescripcionMaterial = item.DescripcionMaterial,
                DoW = (int)item.DiaDeLaSemana, 
                induscomerNoCliente = indusnocliente
            });
        }

Greetings and thanks again

    
answered by 31.03.2017 / 00:15
source
3

There is a tool that can help you, it is called Linqer . This tool can help you convert an query from SQL to Linq and vice versa.

I recommend that you use it, see the behavior you have when making conversions and especially assimilate that is quite similar, although at first glance it seems that SQL and Linq are totally different, do not see it on that side.

Likewise, I recommend you review the official documentation and see how Start working with Linq.

    
answered by 28.03.2017 в 21:57
2

This worked for me:

var context = new DBContext();
            var boletaQuery =
                from b in context.Boletas
                from m in context.Materiales
                from c in context.Clientes
                join i in context.Induscomer on c.NoCliente equals i.NoCliente into indus
                from ind in indus.DefaultIfEmpty()
                where
                b.Material == m.Material && b.Familia == m.Familia && b.NoCliente == c.NoCliente && b.Fecha >= fechaIni &&
                b.Fecha <= fechaFin && b.Status.Equals('A')
                select new
                {
                    b.Boleta,
                    DiaDeLaSemana = SqlFunctions.DatePart("DW", b.Fecha),
                    m.Descripcion,
                    NombreCliente = c.Nombre,
                    induscomerNoCliente = ind.NoCliente
                };
            var result = boletaQuery.ToList();

...........................

var boletaQuery =
            from b in context.Boletas
            join m in context.Materiales on new { b.Familia, b.Material } equals new { m.Familia, m.Material }
            join c in context.Clientes on b.NoCliente equals c.NoCliente
            join i in context.Induscomer on c.NoCliente equals i.NoCliente into indus
            from ind in indus.DefaultIfEmpty()
            where b.Fecha >= fechaIni && b.Fecha <= fechaFin && b.Status == 'A'
            select new
            {
                b.Boleta,
                DiaDeLaSemana = SqlFunctions.DatePart("DW", b.Fecha),
                m.Descripcion,
                NombreCliente = c.Nombre,
                induscomerNoCliente = ind.NoCliente
            };

......................... This is the execution plan of both queries in sql and they have the same cost. ( What is the difference between implicit and explicit joins? )

    
answered by 30.03.2017 в 17:42
2

Interesting your question, but outside of figuring out how to convert it, I suggest you try this software:

LINQPad

It is a very useful tool, it can be used to test the direct linq code on the connection of the BD:

This other program does what you need to convert SQL to linq:

sqltolinq

Apparently both are paid: (

    
answered by 30.03.2017 в 21:20