Desenvolvimento - C#
Cadastro de um Consultório em Windows Forms, com C# e SQL Server – Parte 14
Nesta parte continuaremos nosso sistema de onde paramos, ou seja, vamos alterar nosso DataSet de Pesquisas para resolver o problema do final do artigo anterior. Veremos também como usar LINQ em um de nossos formulários.
por Wellington Balbo de CamargoCadastro de um Consultório em Windows Forms, com C# e SQL Server – Parte 14
Olá pessoal, nesta parte iremos continuar nosso sistema da onde paramos, ou seja, lembram-se que ao clicarmos no botão Localizar do frmCadastroHerdado, ele não carregava o nome do médico e o nome do paciente em nossa tela? Então, vamos resolver isso alterando nosso DataSet de Pesquisas. Veremos também como usar LINQ em um de nossos formulários. Acompanhem:
Perceba que nosso DataSet já contém os nomes do Médico e do Paciente:
Mesmo assim, precisamos alterá-lo para incluir mais informações. Nosso DataTable deverá trazer todos os campos do ConsultaDataTable. Dito isto, altere a query de consulta do PesquisaID como na imagem abaixo:
Faça o mesmo para os outros três TableAdapters de nosso DataTable, alterando a instrução SELECT. O PesquisaDataTable deverá ficar com este aspecto final:
Ok, agora vamos ao nosso frmConsultaHerdado e vamos alterar o método Carrega Valores:
public override void CarregaValores()
{
try
{
//Instancio a classe e o DataRow, que recebe o método PesquisaID de minha classe
AcessoDadosConsulta objConsulta = new AcessoDadosConsulta(_nCodGenerico);
DataRow dr = objConsulta.PesquisaID();
//Se o DataRow for diferente de nulo, preencho as propriedades
if (dr != null)
{
dtConsulta.Value = DateTime.Parse(dr["DATACONSULTA"].ToString());
dtHrInicio.Value = DateTime.Parse(dr["HORAINICIO"].ToString());
dtHrFim.Value = DateTime.Parse(dr["HORAFIM"].ToString());
txtObservacoes.Text = dr["OBSERVACOES"].ToString();
txtNomeMedico.Text = dr["NOMEMEDICO"].ToString();
txtNomePaciente.Text = dr["NOMEPACIENTE"].ToString();
_nCodMedico = int.Parse(dr["IDMEDICO"].ToString());
_nCodPaciente = int.Parse(dr["IDPACIENTE"].ToString());
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
Percebam que já deixei preenchido o código do Médico e do Paciente, para que, na hora em que o usuário for salvar o registro no banco, não dê erro, já que os códigos devem vir preenchidos no momento em que o usuário faz a respectiva consulta.
Aperte F5 para compilar, vá à tela de Consulta, clique em Localizar para testar se nosso método CarregaValores está correto. Selecione uma consulta, clique em OK e veja o resultado:
No método Salvar, apenas inclua a seguinte linha, antes do bSalvar:
objConsulta.bAtivo = true;
bSalvar = (objConsulta.Salvar(sStatus == StatusCadastro.scInserindo));
Assim, passamos o valor true ao campo Ativo, indicando que, no momento em que o registro é criado, a Consulta está ativa no sistema.
Mude algum dado, clique em Salvar e perceba que o registro também está sendo alterado com sucesso. Teste as demais funcionalidades do sistema e veja que está tudo funcionando corretamente.
Basicamente falando, nosso sistema está bem completo. Só que vamos mais além. Seguindo as videoaulas de Luciano Pimenta, vamos usar um pouco de LINQ em nossas consultas no sistema.
Para saber mais sobre LINQ, visite este link. Farei uma série de artigos somente sobre LINQ, com suas vertentes (To Sql, To Objects, To Entities, etc), aguardem!
Um resumo sobre LINQ é que podemos usá-lo para realizar consultas em qualquer fonte de dados, não importa se esta fonte de dados é um banco de dados, ou é um arquivo XML, ou um arquivo texto, ou uma coleção de objetos, etc. O melhor de tudo (pra quem conhece SQL) é que sua sintaxe é quase igual à do SQL, com filtros, ordenações, agregações, cláusulas, e muito mais. Se você não conhece o LINQ, recomendo fortemente a leitura do link acima e deste aqui, que exibe 101 exemplos de uso prático do LINQ em aplicações (em C# é claro!).
Chega de conceitos, vamos à prática! Usaremos o LINQ na tela de Pesquisa de Pacientes.
Antes de alterarmos o método Pesquisar, do frmPesquisaPaciente, precisamos fazer uma alteração na classe de Acesso a Dados. Abra ela, vá à classe AcessoDadosConsulta, copie o método, do tipo DataTable, Pesquisar, cole-o na classe AcessoDadosPaciente e altere seu método, como o código abaixo ilustra:
public DataTable Pesquisar()
{
try
{
//instancio o TableAdapter e o DataTable
dsConsulta.PacienteDataTable dt = new dsConsulta.PacienteDataTable();
PacienteTableAdapter ta = new PacienteTableAdapter();
//uso o método Fill do TableAdapter, passando como parâmetro o DataTable
ta.Fill(dt);
//retorno o DataTable preenchido
return dt;
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
Assim temos um método que nos retorna todos os dados do Paciente (por meio do método Fill, do TableAdapter).
Agora sim, abra o frmPesquisaPaciente e altere o método Pesquisar para o seguinte (explicações a seguir):
//instancio a Classe e o DataTable, que recebe o método Pesquisar
AcessoDadosPaciente acesso = new AcessoDadosPaciente();
DataTable dt = acesso.Pesquisar();
var consulta = from c in dt.AsEnumerable()
where (c.Field<string>("NOMEPACIENTE").Contains(txtPesquisa.Text))
select new
{
_nCodPaciente = c.Field<int>("IDPACIENTE"),
_sNomePaciente = c.Field<string>("NOMEPACIENTE")
};
Obs: lembre-se de declarar o namespace System.Linq.
Começo declarando uma variável chamada consulta, passando o alias c in (em) dt.AsEnumerable(), uso este AsEnumerable, que implementa a interface IEnumerable, para indicar que estou pesquisando em uma coleção. Só esta primeira linha já me retorna todos os dados do Paciente.
Mais preferi filtrar, então uso o where(c.Field<string>(“NOMEPACIENTE”).Contains(txtPesquisa.Text)), (lembrando que o c é meu alias) uso o Field porque estou pesquisando dentro de um DataTable, se fosse por exemplo, dentro de uma coleção não precisaria do Field. Como estou passando o tipo string na pesquisa, isso me permite usar o método Contains (semelhante ao Like do SQL), assim posso refinar minha pesquisa. No parâmetro do Contains, que “espera” uma string, passo meu txtPesquisa.Text, assim ele irá pesquisar somente o valor digitado pelo usuário neste campo.
Após isso, uso o select new para “tipar” os campos que vou retornar em minha pesquisa, ou seja, indico quais campos serão exibidos na pesquisa, atribuindo seus respectivos tipos (int, string...). Eu poderia usar apenas select c; mais assim não teria os campos tipados. Logo após, faço o mesmo que fiz acima, passando o Field, com seu tipo e a respectiva coluna que receberá seu valor.
Pronto, agora minha variável consulta contém os dados da consulta com seus filtros. Agora é só eu “jogar” essa variável dentro de um laço foreach para exibir seus resultados no ListView. Faço desta forma:
lstPesquisa.Items.Clear();
foreach (var registro in consulta)
{
ListViewItem item = new ListViewItem();
item.Text = registro._nCodPaciente.ToString();
item.SubItems.Add(registro._sNomePaciente);
lstPesquisa.Items.Add(item);
}
Perceba que meu foreach ficou parecido com o do método CarregarItens, do frmPesquisaBase.
Veja abaixo como ficou meu método completo:
public override void Pesquisar()
{
try
{
AcessoDadosPaciente acesso = new AcessoDadosPaciente();
DataTable dt = acesso.Pesquisar();
if (rbtCodigo.Checked)
{
var consulta = from c in dt.AsEnumerable()
where (c.Field<int>("IDPACIENTE") == int.Parse(txtPesquisa.Text))
select new
{
_nCodPaciente = c.Field<int>("IDPACIENTE"),
_sNomePaciente = c.Field<string>("NOMEPACIENTE")
};
lstPesquisa.Items.Clear();
foreach (var registro in consulta)
{
ListViewItem item = new ListViewItem();
item.Text = registro._nCodPaciente.ToString();
item.SubItems.Add(registro._sNomePaciente);
lstPesquisa.Items.Add(item);
}
}
else
{
var consulta = from c in dt.AsEnumerable()
where (c.Field<string>("NOMEPACIENTE").Contains(txtPesquisa.Text))
select new
{
_nCodPaciente = c.Field<int>("IDPACIENTE"),
_sNomePaciente = c.Field<string>("NOMEPACIENTE")
};
lstPesquisa.Items.Clear();
foreach (var registro in consulta)
{
ListViewItem item = new ListViewItem();
item.Text = registro._nCodPaciente.ToString();
item.SubItems.Add(registro._sNomePaciente);
lstPesquisa.Items.Add(item);
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
Perceba que, no meu if, nossa consulta LINQ muda um pouco (na primeira linha da consulta), mais nada muito complexo.
Salve e compile a aplicação. Clique em Pacientes e faça uma busca clicando no Localizar. Busque por Nome e Código e perceba que está funcionando corretamente. A diferença é que com LINQ nossas pesquisas são funcionais e performáticas!
Na próxima parte de nossa série de artigos começaremos a usar Relatórios em nossos formulários. Inicialmente usaremos o MicrosoftReportViewer. Não percam!
Disponibilizo o código-fonte do projeto clicando aqui.
Assim finalizo o artigo. Muito obrigado a todos!
Créditos à Luciano Pimenta, que fez as videoaulas e ao Portal Linha de Código, por onde pude baixá-las (mediante assinatura), estudá-las e posteriormente fazer este artigo.
Um abraço, e até o próximo artigo.
Wellington Balbo de Camargo