Usuário com melhor resposta
Retornar apenas os campos específicos em uma consulta linq

Pergunta
-
Boa pessoal, Estou desenvolvendo uma aplicação e estou me beneficiando dos Generics para estas consultas. Todavia, surgiu a necessidade de retornar apenas alguns campos (e não todos) em uma determinada query. Observem meu codesnippet e notem que ela retorna todos os campos de uma consulta e não somente campos específicos:
SistemaEscolarEntities escolar = new SistemaEscolarEntities();
public IQueryable<T> selecionarPorParametro(Expression<Func<T, bool>> where) { return escolar.CreateObjectSet<T>().Where(where); }
public IQueryable<T> selecionarTodos() { return escolar.CreateObjectSet<T>(); }
O que eu gostaria de fazer é algo assim:
SistemaEscolarEntities escolar = new SistemaEscolarEntities(); List<AlunoPesquisa> ls = new List<AlunoPesquisa>(); var consulta = from p in escolar.Aluno where (p.nomeAluno.StartsWith(valor)) select new { p.idAluno, p.matriculaAluno, p.nomeAluno };
Porém preciso de algo genérico pois consultas assim se repetirão pelo sistema inteiro e ficar reescrevendo códigos repetidos, acaba violando um dos pilares da OO que é o reaproveitamento de código. Por isto tentei algo como no código abaixo, mas acabei não obtendo muito sucesso, pois quando pego a string e a jogo dentro de um var e tento percorrê-la, para verificar se já existe um registro ele entende que estou percorrendo uma string e não leva em consideração a consulta em si. Veja o trecho abaixo:
public bool filtroTeste(string classe, string coluna, string valor) { int contador = 0; var valorConsulta = "from p in escolar." + classe + " where p." + coluna + ".equals(" + valor + ")" + " select " + coluna + ";"; var query = valorConsulta; foreach (var item in query) { contador += 1; } if (contador==0) { return true; } else { return false; }
Alguém sabe como fazer para que este último trecho de código seja reconhecido como uma expressão de consulta e não como uma string? ou que os dois métodos com Generics que eu criei retornem campos específicos? pois as duas possibilidades me adiantam.Obrigado.
Respostas
-
Olá A.Martins,
Acredito que vc deve dar uma estudada em Dynamic LINQ.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.wordpress.com/
Twitter: @ferhenrique- Sugerido como Resposta AndreAlvesLimaModerator segunda-feira, 19 de dezembro de 2011 11:33
- Marcado como Resposta Jair Martins segunda-feira, 19 de dezembro de 2011 12:50
-
eu lhe recomendaria dar uma lida sobre Entity SQL
http://olavooneto.wordpress.com/2011/04/08/entity-sql/
http://marquinhosnet.wordpress.com/2010/07/21/usando-entity-sql-para-operacoes-no-banco-de-dados/
http://blogs.msdn.com/b/adonet/archive/2007/05/30/entitysql.aspx
Olavo Oliveira Neto
http://olavooneto.wordpress.com
Twitter @Olavooneto
Se for útil marque como resposta e faça um Developer feliz :)- Marcado como Resposta Jair Martins segunda-feira, 19 de dezembro de 2011 12:58
-
Salve galera! eu encontrei uma solução fácil para o meu problema. Suponhamos que eu quisesse verificar se um usuário existe antes de tentar inserí-lo na base de dados?
Como eu já tinha o método criado abaixo:
public IQueryable<T> selecionarPorParametro(Expression<Func<T, bool>> where) { return context.CreateObjectSet<T>().Where(where); }
na invocação eu do mesmo eu faria o seguinte:string teste = x.selecionarPorParametro(p => p.usuario== "valor").First<Classe>().usuario;
Neste caso vou retornar apenas o atributo pesquisado e se ele existir não cadastro. Caso exista, disparo uma mensagem para o usuário que ficará ciente que existe um valor já cadastrado no banco de dados.Claro que isto de forma genérica e com a maior quantidade possível de reaproveitamento de código.
Pog, I'm your Father.- Sugerido como Resposta Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator quinta-feira, 22 de dezembro de 2011 11:07
- Marcado como Resposta Jair Martins quinta-feira, 22 de dezembro de 2011 11:54
Todas as Respostas
-
Olá A.Martins,
Acredito que vc deve dar uma estudada em Dynamic LINQ.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.wordpress.com/
Twitter: @ferhenrique- Sugerido como Resposta AndreAlvesLimaModerator segunda-feira, 19 de dezembro de 2011 11:33
- Marcado como Resposta Jair Martins segunda-feira, 19 de dezembro de 2011 12:50
-
Opa, dei uma olhada e utilizei a DLL que eles disponibilizam, mas acabei obtendo o mesmo resultado. Na verdade, encontrei algumas soluções na NET que tentei implementar, mas não obtive sucesso!. O jeito é escrever na mão mesmo as consultas que vou ter de fazer. Pois a intenção é que a linha abaixo fosse interpretada como consulta e não como string de acordo com os parâmetros passados pelo método:
"from p in escolar." + classe + " where p." + coluna + ".equals(" + valor + ")" + " select " + coluna + ";";
Todavia, agradeço pela dica!. Acredito que se eu pesquisar com mais calma quem sabe eu não resolva no futuro? mas agora, preciso levar o projeto adiante. -
eu lhe recomendaria dar uma lida sobre Entity SQL
http://olavooneto.wordpress.com/2011/04/08/entity-sql/
http://marquinhosnet.wordpress.com/2010/07/21/usando-entity-sql-para-operacoes-no-banco-de-dados/
http://blogs.msdn.com/b/adonet/archive/2007/05/30/entitysql.aspx
Olavo Oliveira Neto
http://olavooneto.wordpress.com
Twitter @Olavooneto
Se for útil marque como resposta e faça um Developer feliz :)- Marcado como Resposta Jair Martins segunda-feira, 19 de dezembro de 2011 12:58
-
eu lhe recomendaria dar uma lida sobre Entity SQL
http://olavooneto.wordpress.com/2011/04/08/entity-sql/
http://marquinhosnet.wordpress.com/2010/07/21/usando-entity-sql-para-operacoes-no-banco-de-dados/
http://blogs.msdn.com/b/adonet/archive/2007/05/30/entitysql.aspx
Olavo Oliveira Neto
http://olavooneto.wordpress.com
Twitter @Olavooneto
Se for útil marque como resposta e faça um Developer feliz :) -
Salve galera! eu encontrei uma solução fácil para o meu problema. Suponhamos que eu quisesse verificar se um usuário existe antes de tentar inserí-lo na base de dados?
Como eu já tinha o método criado abaixo:
public IQueryable<T> selecionarPorParametro(Expression<Func<T, bool>> where) { return context.CreateObjectSet<T>().Where(where); }
na invocação eu do mesmo eu faria o seguinte:string teste = x.selecionarPorParametro(p => p.usuario== "valor").First<Classe>().usuario;
Neste caso vou retornar apenas o atributo pesquisado e se ele existir não cadastro. Caso exista, disparo uma mensagem para o usuário que ficará ciente que existe um valor já cadastrado no banco de dados.Claro que isto de forma genérica e com a maior quantidade possível de reaproveitamento de código.
Pog, I'm your Father.- Sugerido como Resposta Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator quinta-feira, 22 de dezembro de 2011 11:07
- Marcado como Resposta Jair Martins quinta-feira, 22 de dezembro de 2011 11:54