none
Como retornar uma consulta join feita com Lambda? RRS feed

  • Pergunta

  • Boa tarde pessoal, estou tendo uma dificuldade. Utilizo entity framework e encapsulo minhas consultas no banco de dados em métodos. Num deles gostaria de retornar não todos os dados das tabelas Produto e Categoria, apenas o nome, preço, e a categoria. Tento utilizar a consulta em lambda que possui um join, mas não consigo retornar a lista. Alguém pode me ajudar a retorná-la: existe outro método ao invés do que estou utilizando, estou fazendo errado ou precisa acrescentar algum código?

    Código:

    public ICollection<Produto> FindByNome(string Nome)
            {
                using(Contexto db = new Contexto())
                {
                    var query = db.Produto
                                   .Join(db.Categoria, p => p.IdProduto, c => c.IdCategoria, (p, c) => new { p, c})
                                   .Where(w => w.p.NomeProduto.Contains(Nome))
                                   .Select(s => new
                                   {
                                       nome = s.p.NomeProduto,
                                       preco = s.p.Preco,
                                       categoria = s.c.NomeCategoria,
                                   }).AsQueryable();
    
                    return query.ToList();
                }
            }

    terça-feira, 1 de dezembro de 2015 18:45

Respostas

  • Quando retornamos dados que não existem tipos podemos retornar algum tipo novo criando uma nova classe para esses tipos. Do jeito que você fez vai dar um erro realmente porque os tipos não são iguais.

    Crie uma classe assim:

    public class Dados {
    public string Nome {get;set;}
    public string Categoria {get;set;}
    public decimal Preco {get;set;}
    }

    e no seu método assim:

    public ICollection<Dados> FindByNome(string Nome)
    {
    	using(Contexto db = new Contexto())
    	{
    		var query = db.Produto
    					   .Join(db.Categoria, p => p.IdProduto, c => c.IdCategoria, (p, c) => new { p, c})
    					   .Where(w => w.p.NomeProduto.Contains(Nome))
    					   .Select(s => new Dados()
    					   {
    						   Nome = s.p.NomeProduto,
    						   Preco = s.p.Preco,
    						   Categoria = s.c.NomeCategoria,
    					   }).ToList();
    
    		return query;
    	}
    }

    é uma maneira mais tranquila de trabalha, uma dica que eu dou nunca trabalhei com dados diferenciados em entidades do Entity.


    Fulvio C


    terça-feira, 1 de dezembro de 2015 20:13
  • Sinceramente é única forma de retornar um dado Tipado para uma View, não é feio e não descaracteriza em nada a sua aplicação, o que você tem que entender é que um dado sem tipo que é feio na maioria dos casos (TODA REGRA TEM EXCESSÃO)!

    Um exemplo é quando você gera um dado sem tipo e manda esse dado no formato JSON, NÃO PRECISA NESSE CASO CRIAR UM DADO TIPADO.

    Outro caso se você for usar esse dado em seu código somente sem interação para View também não precisa usar um Dado tipado.

    Ou seja, o problema maior é quando mostrar esse dado em uma View, ele precisa (ai sim boa prática) de um tipo!

    Respondendo seu questionamento, Eu faço JOIN e formato os dados igual tu fez!, porque se eu não tenho necessidade de ter todos os campos uso só o que eu preciso, boa prática nesse aspecto também! Você tem que transformar sua Query igual quando não tinha um ORM, para manter o bom desempenho do banco.


    Fulvio C

    • Marcado como Resposta Marcos SJ quarta-feira, 2 de dezembro de 2015 13:50
    quarta-feira, 2 de dezembro de 2015 12:06

Todas as Respostas

  • var query = from produto in db.Produto 
       join categoria in db.Categoria on produto.IdCategoria equals categoria.IdCategoria
                where produto.NomeProduto.Contains(nome)
                order by produto.NomeProduto descending
                select new 
       {
          nome = produto.NomeProduto,
                   preco = produto.Preco,
                   categoria = categoria.NomeCategoria,
       }


    return query.ToList().select(registro=> new Produto(){ Nome = registro.NomeProduto, Preco = registro.Preco, Categoria = registro.NomeCategoria });

    Você tem que converter o tipo anonimo que foi criado no primeiro select para o tipo que você está retornando.

    terça-feira, 1 de dezembro de 2015 19:03
  • Quando retornamos dados que não existem tipos podemos retornar algum tipo novo criando uma nova classe para esses tipos. Do jeito que você fez vai dar um erro realmente porque os tipos não são iguais.

    Crie uma classe assim:

    public class Dados {
    public string Nome {get;set;}
    public string Categoria {get;set;}
    public decimal Preco {get;set;}
    }

    e no seu método assim:

    public ICollection<Dados> FindByNome(string Nome)
    {
    	using(Contexto db = new Contexto())
    	{
    		var query = db.Produto
    					   .Join(db.Categoria, p => p.IdProduto, c => c.IdCategoria, (p, c) => new { p, c})
    					   .Where(w => w.p.NomeProduto.Contains(Nome))
    					   .Select(s => new Dados()
    					   {
    						   Nome = s.p.NomeProduto,
    						   Preco = s.p.Preco,
    						   Categoria = s.c.NomeCategoria,
    					   }).ToList();
    
    		return query;
    	}
    }

    é uma maneira mais tranquila de trabalha, uma dica que eu dou nunca trabalhei com dados diferenciados em entidades do Entity.


    Fulvio C


    terça-feira, 1 de dezembro de 2015 20:13
  • var query = from produto in db.Produto 
       join categoria in db.Categoria on produto.IdCategoria equals categoria.IdCategoria
                where produto.NomeProduto.Contains(nome)
                order by produto.NomeProduto descending
                select new 
       {
          nome = produto.NomeProduto,
                   preco = produto.Preco,
                   categoria = categoria.NomeCategoria,
       }


    return query.ToList().select(registro=> new Produto(){ Nome = registro.NomeProduto, Preco = registro.Preco, Categoria = registro.NomeCategoria });

    Você tem que converter o tipo anonimo que foi criado no primeiro select para o tipo que você está retornando.

    Mas não possui um tipo para retorno. O select é de 3 tributos de duas classes diferentes do banco de dados. Talvez eu tenha de criar, ainda não sei. Como vc encapsularia em um método essa querie que vc mandou? Seria "public List<Produto> FindAll(){}"?
    • Editado adilsonsousa terça-feira, 1 de dezembro de 2015 23:43
    terça-feira, 1 de dezembro de 2015 23:39
  • Quando retornamos dados que não existem tipos podemos retornar algum tipo novo criando uma nova classe para esses tipos. Do jeito que você fez vai dar um erro realmente porque os tipos não são iguais.

    Crie uma classe assim:

    public class Dados {
    public string Nome {get;set;}
    public string Categoria {get;set;}
    public decimal Preco {get;set;}
    }

    e no seu método assim:

    public ICollection<Dados> FindByNome(string Nome)
    {
    	using(Contexto db = new Contexto())
    	{
    		var query = db.Produto
    					   .Join(db.Categoria, p => p.IdProduto, c => c.IdCategoria, (p, c) => new { p, c})
    					   .Where(w => w.p.NomeProduto.Contains(Nome))
    					   .Select(s => new Dados()
    					   {
    						   Nome = s.p.NomeProduto,
    						   Preco = s.p.Preco,
    						   Categoria = s.c.NomeCategoria,
    					   }).ToList();
    
    		return query;
    	}
    }

    é uma maneira mais tranquila de trabalha, uma dica que eu dou nunca trabalhei com dados diferenciados em entidades do Entity.


    Fulvio C


    Eu pensei em criar uma classe assim como você fez, mas achei meio "feio" e fora do padrão das boas práticas. Como você retorna seus dados utilizando joins com 2 tabelas ou mais do banco de dados?
    terça-feira, 1 de dezembro de 2015 23:40
  • Sinceramente é única forma de retornar um dado Tipado para uma View, não é feio e não descaracteriza em nada a sua aplicação, o que você tem que entender é que um dado sem tipo que é feio na maioria dos casos (TODA REGRA TEM EXCESSÃO)!

    Um exemplo é quando você gera um dado sem tipo e manda esse dado no formato JSON, NÃO PRECISA NESSE CASO CRIAR UM DADO TIPADO.

    Outro caso se você for usar esse dado em seu código somente sem interação para View também não precisa usar um Dado tipado.

    Ou seja, o problema maior é quando mostrar esse dado em uma View, ele precisa (ai sim boa prática) de um tipo!

    Respondendo seu questionamento, Eu faço JOIN e formato os dados igual tu fez!, porque se eu não tenho necessidade de ter todos os campos uso só o que eu preciso, boa prática nesse aspecto também! Você tem que transformar sua Query igual quando não tinha um ORM, para manter o bom desempenho do banco.


    Fulvio C

    • Marcado como Resposta Marcos SJ quarta-feira, 2 de dezembro de 2015 13:50
    quarta-feira, 2 de dezembro de 2015 12:06