Melhor forma de fazer consulta usando linq
05/06/2015
0
Estou utilizando: Enity Framework Code First + Aplicação Windows Form + SGBD MySQL.
No meu formulário de consulta de fornecedor é possível filtrar por Razão, Fantasia e Cnpj. Bom a consulta está funcionando corretamente, pois tenho 3 métodos na minha camada DAL que conforme código abaixo:
public List<Fornecedor> FornecedorGetAllRazao(string FornecedorValueRazao, int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from f in ctx.Fornecedores.ToList() where (f.Razao.Contains(FornecedorValueRazao) && f.Empresa_Id == EmpresaValueId) orderby f.Razao select f; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } } public List<Fornecedor> FornecedorGetAllFantasia(string FornecedorValueFantasia, int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from f in ctx.Fornecedores.ToList() where (f.Fantasia.Contains(FornecedorValueFantasia) && f.Empresa_Id == EmpresaValueId) orderby f.Razao select f; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } } public List<Fornecedor> FornecedorGetAllCnpj(string FornecedorValueCnpj, int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from f in ctx.Fornecedores.ToList() where (f.Cnpj.Contains(FornecedorValueCnpj) && f.Empresa_Id == EmpresaValueId) orderby f.Razao select f; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } }
A minha duvida é: Se eu criar um método BuscarTodos() na minha camada DAL conforme o código abaixo:
public List<Fornecedor> FornecedorGetAll(int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from f in ctx.Fornecedores.ToList() where (f.Empresa_Id == EmpresaValueId) orderby f.Razao select f; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } }
E se eu realizar o filtro da minha pesquisa em cima do método BuscarTodos() usando Lambda como no exemplo abaixo:
private void PesquisarFornecedor() { List<Fornecedor> lista = fornecedorBLL.FornecedorGetAll(EmpresaValueId); if (rbPorRazao.Checked == true) { lista = lista.Where(f => f.Razao.Contains(txtPesquisar.Text)).ToList(); if (lista.Count == 0) { MessageBox.Show("Nenhum registro encontrado", "SIGPRO - Aviso do Sistema", MessageBoxButtons.OK, MessageBoxIcon.Information); lbNumRegistroRetornados.Text = "0"; txtPesquisar.Text = ""; txtPesquisar.Focus(); dgvFornecedorPesquisar.DataSource = null; return; } else if (lista.Count != 0) { dgvFornecedorPesquisar.DataSource = lista; int qtde = lista.Count(); lbNumRegistroRetornados.Text = qtde.ToString(); } } }
Com isso poderia ter um ganho de performance e um menor consumo de recursos de rede eu daria na mesma?
Elessandro Poças
Posts
11/06/2015
Joel Rodrigues
Bom, isso não vai necessariamente lhe dar ganho de performance. Sobre tráfego de rede, vai ser na verdade maior, pois você estará trazendo todos os registros da tabela, ao invés de apenas os que você deseja.
Tire o ToList() da cláusula from das consultas, pois ela é desnecessária e gera uma lista com todos os registros, impactando no resultado final em termos de desempenho.
Abraço.
12/06/2015
Elessandro Poças
Obrigado pela explicação.
Se eu tirar o ToList() das cláusula from a consulta não retorna nenhum dado. Quando eu usava a verão 4 do Entity Framework a mesma consulta funcionava perfeitamente após a versão 5 tive que usar o ToList() na cláusula from pois sem a mesma a consulta não retorna valores como mostrado na imagem em anexo.
[img:descricao=Teste Consulta Linq]http://arquivo.devmedia.com.br/forum/imagem/267760-20150612-090136.png[/img]
Agora não sei se estou fazendo algo de errado, se você puder me ajudar, deste já agradeço.
12/06/2015
Joel Rodrigues
Abraço.
12/06/2015
Elessandro Poças
public List<Cliente> ClienteGetAllNomeRazao(string ClienteValueNomeRazao, int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from c in ctx.Clientes where (c.ClienteNome.Contains(ClienteValueNomeRazao) && c.Empresa_Id == EmpresaValueId) orderby c.ClienteNome select c; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } }
12/06/2015
Joel Rodrigues
12/06/2015
Randrade
Eu estava tendo alguns problemas quando utilizava o entity. Porém, após algumas pesquisas, eu encontrei o Dapper. Em meus testes, triplicou a velocidade de minhas consultas. Porém, se quer performance mesmo, se cada milésimo importa, você terá que fazer isso via SQL puro mesmo, usando o SqlDataReader.
Segue uma tabela comparativa:
[img:descricao=Dapper vs Entity]http://arquivo.devmedia.com.br/forum/imagem/397347-20150612-105103.png[/img]
Esta tabela está desatualizada, o entity hoje está na faixa de 180ms.
12/06/2015
Elessandro Poças
Refiz a consulta da seguinte forma:
public List<Cliente> ClienteGetAllNomeRazao(string ClienteValueNomeRazao, int EmpresaValueId) { try { using (var ctx = new Contexto()) { var consulta = from c in ctx.Clientes.AsEnumerable().Where(c => c.ClienteNome.Contains(ClienteValueNomeRazao) && c.Empresa_Id == EmpresaValueId) orderby c.ClienteNome select c; return consulta.ToList(); } } catch (Exception ex) { throw new Exception(ex.Message); } }
Desta forma o from só buscou os dados que eu precisava, conforme imagem abaixo.
[img]http://arquivo.devmedia.com.br/forum/imagem/267760-20150612-140634.png[/img]
Clique aqui para fazer login e interagir na Comunidade :)