Optimize operation with lambda

2

I have the following classes:

public class Pedidos_Itens
{
    public int ID { get; set; }
    public int Qtde { get; set; }
    public Pedidos _Pedido { get; set; }
    public int Pedido { get; set; }
    public Loja_Produtos _Produto;
    public int Produto { get; set; }
}

E

public class Loja_Produtos
{
    public int ID { get; set; }
    public string Nome { get; set; }
 }

E

public class Pedidos
{
    public int ID { get; set; }
    public DateTime Data { get; set; }
    public decimal Valortotal { get; set; }
}

But the bank has no foreign key and I can not modify ANY bank. So I can not use the include (I believe it's because of the absence of the foreign key). So I did the following:

    public IEnumerable<Pedidos_Itens> ListarTodos()
    {
        var itens = contexto.PedidoItem.ToList();
        var list = new List<Pedidos_Itens>();
        foreach (var i in itens)
        {
            i._Produto = contexto.Produto.First(x => x.ID == i.Produto);
            i._Pedido = contexto.Pedido.First(x => x.ID == i.Pedido);
        }
        return list;
    }

But I believe you have a more efficient way of doing the same.

    
asked by anonymous 11.06.2014 / 14:09

2 answers

1

Example:

As you yourself reported that you do not have a key, then an inner join was made in these tables and the result will be a list.

var resposta = contexto.Pedidos_Itens
                .Join(contexto.Loja_Produtos, pi => pi.Produto, l => l.ID, (pi, l) => new { pi, l })
                .Join(contexto.Pedidos, p => p.pi.Pedido, pe => pe.ID, (p, pe) => new { p, pe })
                .Select(s => new
                {
                    Loja_Produtos_ID = s.p.l.ID,
                    Loja_Produtos_NOME = s.p.l.Nome,
                    Pedidos_Itens_ID = s.p.pi.ID,
                    Pedidos_Itens_QTDE = s.p.pi.Qtde,
                    Pedidos_ID = s.pe.ID,
                    Pedidos_DATA = s.pe.Data, 
                    Pedidos_VALORTOTAL = s.pe.Valortotal
                });

Query is sure to be slow, because of the lack of reported keys and relationships and lack of indexing, but it works somewhat favorably.

With Linq to Objects >:

public IEnumerable<Pedidos_Itens> ListarTodos()
{
    contexto contexto = new ConsoleApplication1.contexto();
    var resposta = contexto.Pedidos_Itens
        .Join(contexto.Loja_Produtos, pi => pi.Produto, l => l.ID, (pi, l) => new { pi, l })
        .Join(contexto.Pedidos, p => p.pi.Pedido, pe => pe.ID, (p, pe) => new { p, pe })
        .Select(s => new
        {
            Loja_Produtos_ID = s.p.l.ID,
            Loja_Produtos_NOME = s.p.l.Nome,
            Pedidos_Itens_ID = s.p.pi.ID,
            Pedidos_Itens_QTDE = s.p.pi.Qtde,
            Pedidos_ID = s.pe.ID,
            Pedidos_DATA = s.pe.Data,
            Pedidos_VALORTOTAL = s.pe.Valortotal
        });

    IList<Pedidos_Itens> ListaPedidosItens = new List<Pedidos_Itens>();
    foreach (var resp in resposta)
    {
        ListaPedidosItens.Add(new Pedidos_Itens()
        {
            ID = resp.Pedidos_Itens_ID,
            Qtde = resp.Pedidos_Itens_QTDE,
            _Pedido = new Pedidos() { ID = resp.Pedidos_ID, Data = resp.Pedidos_DATA, Valortotal = resp.Pedidos_VALORTOTAL },
            _Produto = new Loja_Produtos() { ID = resp.Loja_Produtos_ID, Nome = resp.Loja_Produtos_NOME }
        });
    }
    return ListaPedidosItens.AsEnumerable();
}

Note: It is not very usual to do this, but with Linq to Objects , you will simulate the same thing if you had keys and relationships, not very performative but functional

Why better?

You will execute a single SQL with Inner Join and then in memory the data will be worked with Linq to Objects .

    
11.06.2014 / 15:25
1

I believe this will suit.

var itens = contexto.PedidoItem.Select(pi => new
{
    ID = pi.ID,
    Qtde = pi.Qtde,
    Produto = pi.Produto,
    _Produto = contexto.Produto.FirstOrDefault(pr => pr.ID == pi.Produto),
    Pedido = pi.Pedido,
    _Pedido = contexto.Pedido.FirstOrDefault(pe => pe.ID == pi.Pedido)
}).ToList();
    
11.06.2014 / 14:32