How to avoid repetition in LINQ queries?

5

I have the following LINQ query that is in a method that returns all products:

var query = from p in Produtos
    select new Produto
    {
        ProdutoId = p.ProdutoId,
        Descricao = p.Descricao,
        Preco = p.Preco,
        Estoque = p.Estoque
    };
return query;

I also have other methods that return the same fields being filtered by certain conditions eg:

var query = from p in Produtos
    where p.Descricao.StartsWith(descricao)
    select new Produto
    {
        ProdutoId = p.ProdutoId,
        Descricao = p.Descricao,
        Preco = p.Preco,
        Estoque = p.Estoque
    };
return query;

Is there any way to avoid repeating the snippet:

  select new Produto
  {
      ProdutoId = p.ProdutoId,
      Descricao = p.Descricao,
      Preco = p.Preco,
      Estoque = p.Estoque

  };
     

With this, if you want to add / remove some field, you would not have to change all methods.

Other solutions are also welcome.

    
asked by anonymous 17.01.2016 / 16:04

4 answers

4

I do not know if you fully understand what you need because the code presented is very context-free, it would have been easier if you had put a MCVE . But I think this solves:

public static IEnumerable<Produto> Lista(IEnumerable<Produto> produtos) {
    return from p in produtos
        select new Produto {
            ProdutoId = p.ProdutoId,
            Descricao = p.Descricao,
            Preco = p.Preco,
            Estoque = p.Estoque
        };
}
public static IEnumerable<Produto> FiltreNome(IEnumerable<Produto> produtos, string descricao) {
    var query = from p in produtos
        where p.Descricao.StartsWith(descricao)
        select p;
    return Lista(query);
}

See working on dotNetFiddle .

    
17.01.2016 / 18:09
0

Another way would be:

private static Produto CamposProduto(Produto p)
{
    return new Produto
    {
        ProdutoId = p.ProdutoId,
        Descricao = p.Descricao,
        Preco = p.Preco,
        Estoque = p.Estoque
    };
}

To get the fields would be:

var query = from p in Produtos
    select CamposProduto(p);
return query;
    
10.04.2016 / 04:15
0

Place a DISCTINT () at the end of select

Keep it like this:

var query = from p in Produtos
    where p.Descricao.StartsWith(descricao)
    select new Produto
    {
        ProdutoId = p.ProdutoId,
        Descricao = p.Descricao,
        Preco = p.Preco,
        Estoque = p.Estoque
    }.DISCTINT();
return query;

Hope this helps

    
26.08.2016 / 11:41
0

If your goal is to just return some field from your table you can use Extension Methods , which would function as if you were using any other Linq method, and you still have the facility to use as many filters as you need where you query and create typed list yet or leave anonymous type

using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace stackoverflow
{
    public partial class BuscarProdutos : Page
    {
        protected void Load_Produtos()
        {
            using (var ctx = new stackoverflowEntities())
            {
                var query =  ctx.Produtos
                    .Where(p => p.Descricao.StartsWith("descricao")) // aqui você pode por quantos filtros forem necessarios.
                    .Vw_Produto(ctx); // aqui você chama seu Métodos de extensão. (Vw_Produto)

                // enquanto a query for um IQueryable você pode fazer filtro tipo
                bool campo1 = true, campo2 = true;
                if(campo1 == campo2)
                {
                    query = query.Where(p => p.ProdutoId == 1);
                }

                // para execulta sua query user o ToList(); ou em algum tipo de loop, isso lançara uma consulta 
                // no banco de dados
                var lista = query.ToList();
            }
        }
    }

    public class cvw_Produto
    {
        public string Descricao { get; internal set; }
        public int? Estoque { get; internal set; }
        public decimal? Preco { get; internal set; }
        public int ProdutoId { get; internal set; }
    }

    public static class ProdutoExt
    {
        public static IQueryable<cvw_Produto> Vw_Produto(
                this IQueryable<Produto> qrIn, stackoverflowEntities ctx)
        {
            return qrIn
                .Select(p => new cvw_Produto // Com tipo ou deixe só o new para ficar tipo anonimos.
                {
                    ProdutoId = p.ProdutoId,
                    Descricao = p.Descricao,
                    Preco = p.Preco,
                    Estoque = p.Estoque
                });
        }
    }
}
    
26.08.2016 / 14:40