Neste artigo eu vou mostrar como
usar um serviço com acesso a dados com LINQ to SQL para
consultar um banco de dados SQL Server.
Eu vou usar como exemplo neste artigo o banco de dados Macoratti.mdf e vou trabalhar com a tabela
Categories.
O banco de dados Macoratti.mdf é uma réplica
simplificada do banco de dados Northwind.mdf e possui a estrutura
exibida na figura abaixo. Em detalhes vemos a tabela Categorias com os seus
campos e alguns dados informados:
O objetivo é reforçar os conceitos do WCF e mostrar
uma forma simples de usar um serviço WCF sendo consumido por uma aplicação
Windows Forms com LINQ To SQL.
Para realizar tal tarefa irei criar
uma solução contendo 3 projetos assim descritos:
- ServicoWCF – Projeto contendo o serviço WCF onde iremos definir um contrato que descreve a tarefa que o serviço vai expor através do contrato; (O contrato é uma interface que contém as assinaturas dos métodos que serão expostos. A interface deverá ser decorada com o atributo:ServiceContract)
– GetDataCategorias() – que irá acessar a tabela Categorias e retornar todos os seus dados;
- DAL_Linq – Projeto class Library que atuará como uma camada de acesso a dados usando LINQ to SQL;
– Geração do mapeamento ORM da tabela Categorias para a entidade Categorias;
- WindowsConsomeWCF – Projeto Windows Forms que irá consumir o serviço acessando e exibindo os dados;
– Utilização de um controle DataGridView em um formulário para exibir as categorias da tabela Categorias ;
Apenas para relembrar, cada serviço, para ser
exposto através do WCF, precisa atender os seguintes requisitos:
- Possuir um contrato e a sua implementação
concreta; - Possuir um configuração de Binding; (configuração
de como um EndPoint de um serviço WCF se comunica com outros EndPoints) - Possuir ao menos um EndPoint; (define
como as funcionalidades do WCF serão acessadas)
Estes requisitos são conhecidos como ABC:
um
serviço tem que ter um endereço de Endpoint (Address), um Binding
e um Contrato.
Uma coisa que eu não mencionei no artigo anterior
foram as configurações de Binding fornecidas pela infra-estrutura WCF.
O Binding é responsável por indicar como a
comunicação vai ser feita com um endpoint, qual o transporte será usado (HTTP,TCP,
etc.), qual a codificação vai ser usada (Texto
ou Binário) para serializar as mensagens, transações, segurança, etc.
A seguir temos as principais configurações de Binding que podem ser
usadas conforme a utilização e a definição de como será hospedada o seu serviço
WCF:
Nome | Protocolo | Definição |
BasicHTTPBinding | HTTP | – Usa o protocolo HTTP para as comunicações como meio de transporte, sendo que as mensagens são definidas em XML como os Web Services. – O modo de transferência pode ser Streaming ou Buffered, sendo a última o default. – Não dá suporte a transações; – Segurança: None, Transport, Message e Mixed. None é a default. |
WSHTTPBinding | HTTP | -Idêntico ao BasicTTPBinding só que permitindo mais recursos, como transações, segurança na mensagem enviada, etc. – O modo de transferência Buffered. – Dá suporte a transações; – Segurança: None, Transport, Message e Mixed. Message é a default. |
NetTCPBinding | TCP | -Usa o protocolo TCP para as comunicações; as mensagens são codificadas no formato binário; |
NetNamedPipeBinding | Windows Named Pipe | -Usa o protocolo Windows Named Pipe para as comunicações; as mensagens são definidas no formato binário; É usado para cenários onde o host e o cliente estão hospedados na mesma máquina. – Não dá suporte a transações; – Transporte IPC; |
Obs: Ainda existe a
possibilidade de você customizar o seu Binding usando a classe CustomBinding.
Esta definição pode ser feita no arquivo web.config.
Veja abaixo um exemplo de um arquivo web.config exibindo a configuração
do Binding:
Neste exemplo o endereço
do endpoint está vazio (
<endpoint
address=””
), permitindo que IIS use o endereço padrão.
.........
<services>
<service name="ServicoWCF.Service1" behaviorConfiguration="ServicoWCF.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="ServicoWCF.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
......
Eu vou usar o Visual Studio 2008 SP1 para criar a
solução deste artigo.
Criando a solução e os
projetos
Abra o Visual Studio 2008 SP1
(se você não tiver
o VS 2008, pegue a versão trial por 90 dias
aqui) e no menu File selecione New Project ou clique diretamente em Create Project;
Na janela New Project selecione : Other Project
Types e a seguir Visual Studio Solutions e, em Templates, selecione
Blank Solution
e informe o nome Usando_LINQ_WCF e escolha a localização do projeto;
Vamos agora incluir o projeto do tipo Class Library
chamado DAL_Linq que será a nossa camada de acesso a dados onde iremos usar o LINQ to SQL.
No menu File selecione selecione Add e a seguir New
Project;
Na janela Add New Project selecione Visual Basic,
e, em
Templates, selecione Class Library e informe o nome DAL_Linq e clique em
OK;
Agora vamos incluir outro projeto, o projeto WCF,
onde iremos definir o serviço que iremos consumir. Iremos usar o template
WCF Service Application que já fornece a infra-estrutura básica para usar
o serviço.
No menu File selecione selecione Add e a seguir New
Project;
Na janela Add New Project selecione Web, e, em
Templates, selecione
WCF Service Application, informe o nome ServicoWCF e clique
em OK;
Por último vamos incluir um projeto
Windows Forms
que irá consumir o serviço criado no WCF.
No menu File selecione selecione Add e a seguir New
Project;
Na janela Add New Project selecione Windows
e, em Templates, selecione Windows Forms Application informe o nome WindowsConsumeWCF e clique em OK;
Ao final desta etapa a sua solução deverá exibir na
janela Soluction explorer os seguintes projetos:
Definindo a camada de
acesso a dados – DAL_Linq
Vamos definir a camada de acesso a dados usando o
LINQ to SQL. Para isso vamos excluir a classe class1.vb criada por padrão. Feito
isso vamos verificar se existe uma conexão com o banco de dados que desejamos
usar. Neste exemplo eu vou usar o banco de dados Macoratti.mdf.
Abra o Server Explorer e se a conexão com o banco
de dados não aparecer na janela, clique em Add Connection e informe o nome do
servidor e selecione o Banco de dados Macoratti.mdf ou outro que você quiser usar e
clique em OK;
Agora vamos clicar com o botão direito do
mouse sobre o nome do projeto e selecionar a opção Add New Item;
Selecione o template LINQ to SQL Classes
e informe
o nome Categorias.dbml e clique em Add;
Abra a janela Server Explorer, expanda os objetos
do banco de dados Macoratti.mdf e arraste e solte a tabela Categorias no
descritor LINQ para criar a entidade Categoria. Neste momento será criado o
mapeamento OR/M. Observe que foi criado o DataContext
CategoriasDataContext.
Selecione a propriedade Serialization Mode
do DataContext e defina o seu valor como Unidirectional,
com isso teremos a serialização requerida pelo serviço WCF.
Feito isso, salve o projeto.
Definindo o serviço WCF
em : ServicoWCF
Para definir o serviço WCF, primeiro temos que
incluir uma referência ao nosso projeto DAL_Linq. Clique com o botão direito do
mouse sobre o projeto ServicoWCF e selecione Add Reference;
Na janela Add Reference selecione a guia Projects,
selecione DAL_Linq e clique em OK;
Abra o arquivo de interface IService1.vb e remova
todo o código existente. A seguir inclua o código que define o método
GetDataCategorias() que retorna uma Lista de Categorias do tipo
DAL_Linq.Categoria;
Observe que os atributos <ServiceContratct()> e <OperationContract()> são obrigatórios para definir o contrato do serviço. O
atributo ServiceContract serve para indicar que a interface é um serviço
WCF e o atributo OperationContract indica que o método será exportado e
estará visível para os clientes do serviço.
Agora temos que implementar o método definido na
interface no arquivo Service1.svc. Selecione o arquivo e remova todo o código
existente definindo o código conforme mostrado na figura abaixo:
Obs: Você terá que incluir uma
referência a System.Data.Linq
neste projeto.
O método GetDataCategorias retorna uma
coleção de Categorias usando uma consulta LINQ. Após isso, salve o projeto.
Consumindo o serviço em
uma aplicação Windows Forms: WindowsConsomeWCF
Vamos agora criar uma interface simples incluindo
um controle DataGridView no formulário form1.vb do
projeto WindowsConsomeWCF;
Inclua um controle DataGridView-
gdvCategorias e um controle Button –
btnExibir conforme a figura abaixo:
Feito isso, clique com o botão direito do mouse
sobre o projeto Windows e selecione a opção Add Service Reference;
Clique no botão Discover e selecione
Services in Solution;
Ocorrendo tudo como previsto, o serviço que criamos
será encontrado e exibido na janela Services;
Clique no serviço Service1.svc
e o método GetDataCategorias() será exibido na janela Operations;
Podemos alterar o nome do namespace sugerido,
mas eu vou usar o nome indicado: ServiceReference1;
Antes de encerrar, precisamos efetuar um pequeno
ajuste. Clique no botão Advanced… e altere o tipo de dados para
System.Collections.Generic.List, pois este é o tipo
de dados que será retornado pelo nosso serviço.
Após isso, clique em OK;
Você deverá ver no seu projeto
WIndows Forms a referência ao serviço criada conforme a figura abaixo:
Agora vamos usar o serviço incluindo no evento
Click do botão Exibir Categorias o seguinte código:
O código é simples, estou criando uma instância do
meu serviço definido em ServiceReference1;
A seguir estou acessando o método
getDataCategorias(), definido no serviço que retorna uma coleção de
categorias e exibindo no controle
DataGridView.
O resultado pode ser visto na figura abaixo:
Com isso concluímos a nossa primeira aplicação que
consome um serviço WCF com acesso a dados usando o LINQ to SQL.
Pegue a solução completa aqui:
Usando_LINQ_WCF.zip
E o banco de dados aqui: Macoratti.mdf
Eu sei, é apenas WCF e LINQ, mas eu
gosto…