Desenvolvimento - Silverlight

Criando uma aplicação Silverlight que acessa uma base de dados PostgreSQL 8

Neste tutorial vou mostrar uma forma de criar uma aplicação Silverlight que acessa informações de um banco de dados, em vez de utilizar uma base de dados SQL Server, vou utilizar um excelente banco de dados, o PostgreSQL.

por Alexandre Tadashi



O Silverlight vem evoluindo de uma forma muito rápida, oito meses se passaram desde a versão final do Silverlight 2 e sua evolução em relação a versão anterior, mostra que em um pequeno espaço de tempo a Microsoft investiu muito em melhorias e está apostando firme nessa tecnologia. Está cada vez mais prático criar aplicações ricas para a Web principalmente se você já tem conhecimento em ambientes de desenvolvimento Microsoft.

Neste tutorial vou mostrar uma forma de criar uma aplicação Silverlight que acessa informações de um banco de dados, em vez de utilizar uma base de dados SQL Server, vou utilizar um excelente banco de dados, o PostgreSQL.

Estou utilizando nesse tutorial o Visual Studio 2008 Professional com Service Pack 1, Silverlight Tools e o PostgreSQL 8.

Para que uma aplicação .NET possa interagir com o PostgreSQL 8 precisamos de uma forma de conexão, nesse tutorial utilizei o Npgsql, ele é um .Net Data Provider feito para o acesso ao PostgreSQL escrito em C# , o download pode ser feito  no endereço abaixo:

http://pgfoundry.org/projects/npgsql/

O Arquivo é o Npgsql2.0.6-bin-ms.net3.5sp1.zip

Objetivo do Tutorial

O Objetivo do projeto web é apresentar na tela uma lista de clientes (nome e telefone) e que permita adicionar novos nomes registrando na base de dados.

Criando as tabelas do tutorial no PostgreSQL 8

Crie uma base de dados no PostgreSQL 8 com o nome de dbCadastro e em seguida crie as tabelas conforme o script abaixo:

-- Sequence: cliente_id_cliente_key

-- DROP SEQUENCE cliente_id_cliente_key;

CREATE SEQUENCE cliente_id_cliente_key

  INCREMENT 1

  MINVALUE 1

  MAXVALUE 9223372036854775807

  START 18

  CACHE 1;

ALTER TABLE cliente_id_cliente_key OWNER TO postgres;

-- Table: cliente

-- DROP TABLE cliente;

CREATE TABLE cliente

(

  id_cliente bigint NOT NULL DEFAULT nextval((""cliente_id_cliente_key""::text)::regclass),

  nm_cliente character varying(120),

  no_telefone character varying(25),

  CONSTRAINT cliente_pkey PRIMARY KEY (id_cliente)

)

WITH (OIDS=TRUE);

ALTER TABLE cliente OWNER TO postgres;

Criando a Solution do Projeto

Crie uma solution para agrupar todos os projetos que farão parte, para isso, abra o Visual Studio 2008 e clique em  File->New->Project->Other Project Types->Visual Studio Solutions. Dê o nome de  “SolutionCadastro”

 

Criando o projeto de Acesso aos dados

Esse projeto tem o objetivo de acessar diretamente a base de dados, contendo métodos de abertura e fechamento da base de dados, além de métodos de apoio.

Clique com o botão direito na solução criada e em Add->New Project->Class Library e dê o nome de “DAO”. Renomeie a “Class.cs” que foi criado automaticamente para “clsDados.cs”

Crie uma pasta chama “DLL” (botão direito->Add->New Folder) no projeto Dados. Descompacte o arquivo Npgsql2.0.6-bin-ms.net3.5sp1, copie cole os arquivos Npgsql.dll e Mono.Security.dll na pasta dll criada.

Adicione os dois arquivos da pasta dll como referencia ao projeto clsDados, para isso, clique em “References->Add References->Browser->dll

A string de conexão do PostgreSQL é:

"Server=127.0.0.1;Port=5432;UserId=postgres;Password=xxxx;Database=dbCadastro;";

Adicione agora um método para abrir a base de dados e outro para fecha-la:

private NpgsqlConnection AbrirBanco()

        {

            createStringconnection();

            NpgsqlConnection cn = new NpgsqlConnection(this.conexao);

            cn.Open();

            return cn;

        }

private void FecharBanco(NpgsqlConnection cn)

        {

            if (cn.State == System.Data.ConnectionState.Open)

                cn.Close();

                cn.Dispose();

        }

Vamos criar agora dois métodos que tem o objetivo de executar uma instrução SQL (insert, update ou delete) e outro método para as consultas que retornar um NpgsqlDataReader.

public void Execute(Npgsql.NpgsqlCommand cmdIns)

        {

            NpgsqlConnection cn = new NpgsqlConnection(this.conexao);

            try

            {

                cn = AbrirBanco();

                cmdIns.Connection = cn;

                cmdIns.Prepare();

                cmdIns.ExecuteNonQuery();

                cmdIns.Dispose();

            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally

            {

                FecharBanco(cn);

            }

        }

public NpgsqlDataReader Find(StringBuilder  strQuery)

        {

            NpgsqlConnection cn = new NpgsqlConnection(this.conexao);

            try

            {

                cn = AbrirBanco();

                NpgsqlCommand cmd = cn.CreateCommand();

                cmd.CommandText = strQuery.ToString();

                cmd.Connection = cn;

                return cmd.ExecuteReader(); ;

            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally

            {

                FecharBanco(cn);

            }

        }

Criando o projeto de transferência de dados

Vamos criar agora o projeto que tem o objetivo transferir entre as camadas os valores dos objetos.

Clique com o botão direito na solução criada e em Add->New Project->Class Library e dê o nome de “DTO”. Renomeia a Class.cs criado para “Cliente.cs”.

Insira o código conforme abaixo :

public class Cliente

    {

        public string Nm_cliente { get; set; }

        public string No_telefone { get; set; }

        public int Id_cliente { get; set; }

    }

public class ClienteCollection : List<Cliente> { }

Criando o projeto de negócios

Neste projeto vamos criar uma classe que vai receber os dados dos formulários  preparando  para passar para ao projeto que vai trabalhar na persistência na base de dados.

Clique com o botão direito na solução criada e em Add->New Project->Class Library e dê o nome de “BO”. Renomeia a Class.cs criado para “clsCliente.cs”.

Adicione as referenciass aos projetos DTO e DAO. (botão direito->Add References->Projects) e adicione a referência ao Npgsql2.

Método de Inclusão:

     public void Create(Cliente cliente)

        {

            StringBuilder csql = new StringBuilder();

            csql.Append("Insert Into Cliente");

            csql.Append("(");

            csql.Append(" nm_cliente, ");

            csql.Append(" no_telefone ) Values(");

            csql.Append(" :nm_cliente, ");

            csql.Append(" :no_telefone) ");

            Npgsql.NpgsqlCommand c = new Npgsql.NpgsqlCommand();

            c.CommandText = @csql.ToString();

            c.Parameters.Add("nm_cliente", cliente.Nm_cliente);

            c.Parameters.Add("no_telefone", cliente.No_telefone);

            conn.Execute(c);

        }

Método de Consulta

     public ClienteCollection SelectAll()

        {

            StringBuilder csql = new StringBuilder();

            csql.Append("Select ");

            csql.Append(" id_cliente, ");

            csql.Append(" nm_cliente, ");

            csql.Append(" no_telefone ");

            csql.Append(" from cliente");

            NpgsqlDataReader reader = conn.Find(csql);

            ClienteCollection listCliente = new ClienteCollection();

            while (reader.Read())

            {

                Cliente cliente = BuildFromReader(reader);

                listCliente.Add(cliente);

            }

            return listCliente;

        }

public Cliente BuildFromReader(NpgsqlDataReader reader)

        {

            Cliente cliente = new Cliente();

            cliente.Id_cliente = Convert.ToInt32(reader["id_cliente"]);

            cliente.No_telefone = Convert.ToString(reader["no_telefone"]);

            cliente.Nm_cliente = Convert.ToString(reader["nm_cliente"]);

            return cliente;

        }

 

Criando o Web Site e o Web Service

Vamos criar um web site que vai conter o webservice que faz a chamada aos métodos que interagem com a camada de negócios.

File->Add->New Web Site->Add New Web Site

Adicione as referencias BO e DTO.

Botão direito no website->Add New Item->Web Service

Dê o nome de WSCliente.asmx

Insira no web service os dois métodos abaixo:

  clsCliente objClsCliente = new clsCliente();

       

  [WebMethod]

        public void Inserir(Cliente obj)

        {

            objClsCliente.Create(obj);

        }

  [WebMethod]

        public ClienteCollection Consultar()

        {           

         return objClsCliente.SelectAll();

        }

Criando o projeto Silverlight

Finalmente vamos criar a camada de visualização do projeto:

File->add->New Project->Add New Project->Silverlight Application

Neste exemplo vou colocar o nome do projeto de SLCadastro.

 

Inclua uma referencia ao Web Service do Projeto Web Site:

Botão direito->Add Service Reference->Discovery e adicione o WebService com o nome de ServiceReferenceCliente.

Abra o arquivo MainPage.xaml e insira um DataGrid  conforme o código abaixo:

<Grid x:Name="LayoutRoot">

            <data:DataGrid x:Name="dg" AutoGenerateColumns="False" Margin="0,0,0,23">

<data:DataGrid.Columns>

                    <data:DataGridTextColumn Header="Nome" Binding="{Binding Nm_cliente}" Width="400" />

                    <data:DataGridTextColumn Header="Telefone" Binding="{Binding No_telefone}" Width="150" />

                    </data:DataGrid.Columns>

</data:DataGrid>

Temos um DataGrid que contém duas colunas que carregará através de “binding” o nome e o telefone do cliente.

Adicione logo abaixo um botão que vai chamar o formulário de cadastro de clientes:

<Button x:Name="btnCadastro" Height="20" Margin="170,0,143,-1" VerticalAlignment="Bottom"

        Content="Cadastro"

        Click="btnCadastro_Click"/>

No código C# do MainPage vamos no evento loaded chamar a consulta do web service e após a conclusão vamos jogar o resultado para o DataGrid.

private void UserControl_Loaded(object sender, RoutedEventArgs e)

        {

            WSCliente.ConsultarAsync();

    

            WSCliente.ConsultarCompleted +=new EventHandler<ConsultarCompletedEventArgs>(WSCliente_ConsultarCompleted);

                       

        }

void WSCliente_ConsultarCompleted(object sender, ConsultarCompletedEventArgs e)

        {

            if (e.Error == null)

                dg.ItemsSource = e.Result;

        }

Aqui vamos chamar a tela de cadastro:

 

        private void btnCadastro_Click(object sender, RoutedEventArgs e)

        {

            FrmCliente frmCliente = new FrmCliente();

            this.Content = frmCliente;

        }

O Resulado pode ser visto na figura abaixo:

Crie um novo UserControl Silverlight com o nome FrmCliente, onde vamos inserir o formulário de cadastro com os campos TextBox referente ao nome e telefone do cliente e um botão para salvar e outro para fechar a tela, deixe o código xaml conforme a listagem abaixo:

<UserControl

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    x:Class="SLCadastro.FrmCliente"

    Width="640" Height="480" mc:Ignorable="d">

    <Grid x:Name="LayoutRoot"

          Background="White"

          HorizontalAlignment="Left"

          Height="480"

          VerticalAlignment="Top">

        <StackPanel Orientation="Vertical" Margin="0,0,2,0">

               

            <Border CornerRadius="4"

                        BorderBrush="Gray"

                        BorderThickness="1"

                        Margin="5" Background="#FFA19F9F">

                   

                <Grid Margin="1,4,2,4"

                      Height="51"

                      d:LayoutOverrides="Height"

                      Background="#FFCBCBCB">

                        <Grid.RowDefinitions>

                            <RowDefinition Height="Auto"/>

                            <RowDefinition Height="Auto"/>

                            <RowDefinition Height="Auto" MinHeight="7"/>

                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="Auto"/>

                            <ColumnDefinition Width="Auto" MinWidth="290"/>

                        </Grid.ColumnDefinitions>

                        <TextBlock Text="Nome:" Grid.Row="0" Grid.Column="0"

                                   FontWeight="Bold" TextAlignment="Right"

                                   VerticalAlignment="Center" Margin="0,4,2,0" />

                        <TextBox x:Name="txtNm_Cliente" Grid.Row="0" Grid.Column="1" Padding="0"

                                 Height="20" Width="233" HorizontalAlignment="Left" Margin="0,4,0,0"/>

                        <TextBlock Text="Telefone:" Grid.Row="1" Grid.Column="0" FontWeight="Bold"

                                   TextAlignment="Right" VerticalAlignment="Center" Margin="0,4,2,0"/>

                        <TextBox x:Name="txtNo_telefone" Grid.Row="1" Grid.Column="1" Padding="0"

                             Height="20" Width="233" HorizontalAlignment="Left" Margin="0,1,0,-1"/>

                    </Grid>

                </Border>

                <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right">

                    <Button x:Name="btnSalvar" Content="Salvar" Height="20" Width="139" HorizontalAlignment="Center" VerticalAlignment="Center" Click="btnSalvar_Click"   />

                    <Button x:Name="btnFechar" Content="Fechar" Height="20" Width="125" Margin="5,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Click="btnFechar_Click"  />

                </StackPanel>

            </StackPanel>

       

    </Grid>

</UserControl>

E no código C# do FrmCadastro vamos inserir a gravação dos dados e o fechamento da tela:

   private void btnSalvar_Click(object sender, RoutedEventArgs e)

        {

            cliente = new Cliente();

            cliente.Nm_cliente = txtNm_Cliente.Text;

            cliente.No_telefone = txtNo_telefone.Text;

            //Chama o Web Service passando como paramento o cliente

//para a inclusão na base de dados

WSCliente.InserirAsync(cliente);

        }

        private void btnFechar_Click(object sender, RoutedEventArgs e)

        {

//Abre a página principal

//O Evento loaded do MainPage.xaml atualiza o DataGrid 

            MainPage frmMainPage = new MainPage();

            this.Content = frmMainPage;

        }

A figura abaixo mostra o resultado do formulário de cadastro:

Conclusão

RIA – Rich Internet Application é o assunto do momento, junto com a computação nas nuvens espera-se uma experiência mais rica com os aplicativos na web e o Silverlight é a aposta da Microsoft para as tecnologias RIAs.

 

O PostgreSQL vem chamando bastante atenção ultimamente, e a cada dia vem ganhando destaque por ser um banco de dados robusto,livre e vem sendo uma alternativa interessante para vários tipos de situações, reduzindo os custos de uma  implantação.

Existem algumas maneiras de trabalhar com aplicações Silverlight que acessam uma base de dados, dá forma que fizemos nesse tutorial você facilmente consegue fazer um CRUD utilizando o PostgreSQL 8, e pode aprimorar esse exemplo para a utilização em  um projeto real.

Alexandre Tadashi

Alexandre Tadashi - Gerente de projetos da H2 Sistemas, trabalha com desenvolvimento de sistemas .NET destacando-se aplicações windows, asp e silverlight. A H2 Sistemas é um empresa de tecnologia que trabalha com o desenvolvimento de softwares sob medida.