VB .NET - Curso Prático ADO .NET - Desenvolvendo uma aplicação : Definindo o modelo de dados - IV


Na  terceira parte do curso abordamos de forma resumida as fases do projeto com ênfase no projeto de alto nível.

Nesta quarta parte do nosso curso prático vamos definir o nosso modelo de dados onde iremos criar o banco de dados e as tabelas usadas em nossa aplicação.

Vamos definir um modelo bem simples de forma a podermos tratar o assunto no nível básico.

Um decisão importante é a definição de qual gerenciador de banco de dados (SGBD) vamos usar em nosso projeto. Vários fatores influenciam essa decisão, dentre eles o custo, a disponibilidade, a confiabilidade, tamanho da aplicação, Sistema Operacional, Linguagem de programação, etc.

Existem no mercado diversos bancos de dados relacionais que podem ser considerados. Vejamos os principais:

  1. MySQL - Parcialmente free, robusto e indicado para pequenas e médias aplicações;
  2. PostGreSQL - Totalmente free, robusto e confiável. Administração mais complexa.
  3. FireBird - Totalmente free e indicado para pequenas aplicações;
  4. SQL Server - Pago. Robusto e confiável e fácil de administrar;
  5. SQL Server Express ou LocalDB - É  uma edição gratuita do SQL Server que constitui a plataforma de dados ideal para o aprendizado e a criação de aplicativos de desktop e pequenos aplicativos de servidor e você tem a liberdade de redistribuí-lo com aplicativos. Veja abaixo as limitações dessa versão:
Máxima capacidade computacional utilizada por uma única instância.  Menos de 1 soquete ou 4 núcleos.
Máxima capacidade computacional utilizada por uma única instância  Menos de 1 soquete ou 4 núcleos.
Memória máxima utilizada 1 GB
Memória máxima utilizada (Analysis Services) N/A
Memória máxima utilizada (Reporting Services) N/A
Tamanho máximo da Database 10 GB
  1. Oracle - Pago. Robusto e confiável.(Possui a versão free Oracle Database Express Edition 11g Release 2 )

Existem também outros meios de armazenamento de informações como arquivos textos, arquivos xml e também os bancos de dados NoSQL como o MongoDB.

Embora eu não tenha citado, o Microsoft Access pode ser considerado como uma alternativa para projetos pequenos (que se mantenham pequenos) e caseiros ou protótipos.

Para o nosso artigo a equipe de desenvolvimento decidiu utilizar o banco de dados SQL Server no projeto por ser um banco robusto de custo acessível e por sua integração com o Visual Studio, o ambiente de desenvolvimento que iremos usar.

No projeto eu vou usar a nova versão do SQL Server Express LocalDB conhecida como LocalDB, mas você também pode usar o SQL Server Express Edition. Utilizando o SQL Server LocalDB poderemos migrar facilmente as informações para a versão do SQL Server quando da implantação da nossa aplicação em ambiente de produção.

1- SQL Server Express LocalDB

SQL Server Express LocalDB é uma versão leve do SQL Server que tem muitas características de programação de um banco de dados SQL Server. O SQL Server Express LocalDB é executado no modo de usuário e tem uma instalação rápida sem a necessidade de configuração.

No Microsoft SQL Server, o banco de dados ou qualquer código Transact-SQL podem ser movidos de SQL Server Express LocalDB para o SQL Server e SQL Azure, sem quaisquer passos de atualização.

Então, o SQL Server Express LocalDB pode ser usado como um ambiente de desenvolvimento para aplicações que utilizem todas as edições do SQL Server.

O SQL Server Express LocalDB permite recursos como procedimentos armazenados, funções definidas pelo usuário e agregados, Integração com NET Framework, tipos espaciais e outros recurso que não estão disponíveis no SQL Server Compact.

Para criar o banco de dados SQL Server podemos usar o próprio ambiente do Visual Studio ou uma ferramenta de administração para o SQL Server como o SQL Server Management Studio.

Para que todos possam acompanhar o artigo eu vou criar o banco de dados no próprio ambiente do Visual Studio 2012 Express for desktop que é uma ferramenta grátis e funcional que vamos usar para criar o nosso projeto. (Você também pode usar o Visual Studio 2012 ou o Visual Studio 2010 para criar o projeto)

Criando o banco de dados e as tabelas

Abra o Visual Studio 2012 Express for Desktop e no menu VIEW -> Other Windows -> DataBase Explorer;

A seguir clique com o botão direito sobre o item DataConnections na janela DataBase Explorer e clique em Add Connection;

Na janela Add Connection, em Server Name informe (LocalDB)\v11.0 (você pode informar também .\sqlexpress para acessar o SQL Server Express Local) e a seguir informe o nome CiaFilmes que será o nome do nosso banco de dados;

Ao clicar no botão OK, como banco de dados ainda não existe será apresentada uma tela solicitando a sua confirmação para criar o banco de dados. Clique em Sim.

Você deverá ver o nome da conexão exibindo o nome do banco de dados criado e os seus objetos. Para criar as tabelas clique sobre o item Tables e a clique em Add New Table;

No descritor para criação das tabelas temos 3 seções :

  1. Na seção indicada pelo número 1 você informa o nome do campo, o tipo de dados, indica se o campo suporta ou não valores null e define o campo como chave primária;
  2. Na seção indicada pelo número 2 será exibida o script que é gerado conforme definimos a tabela na área 1;
  3. Na seção indicada pelo número 3 temos a janela de propriedades onde podemos definir vários itens. Nesta seção definimos o campo como do tipo identity;

Após informar e verificar os nomes, tipos e definições dos campos você tem que realizar duas ações:

  1. Na seção 2 você deve informar o nome da tabela logo após o comando CREATE TABLE [dbo.Nome_Da_Tabela]
  2. Na seção 1, na parte superior esquerda, temos a opção Update que deve ser acionado para efetivamente criar a tabela;

CREATE TABLE [dbo].[Table]

(

[ClienteId] INT NOT NULL PRIMARY KEY IDENTITY,

[Nome] NVARCHAR(50) NULL,

[Sobrenome] NVARCHAR(50) NULL,

[Endereco] NVARCHAR(50) NULL,

[Cidade] NVARCHAR(50) NULL,

[Estado] NCHAR(2) NULL,

[Cep] NCHAR(8) NULL,

[Telefone] NVARCHAR(50) NULL,

[Email] NVARCHAR(100) NULL,

[Nascimento] DATE NULL,

[NumeroCartaoCredito] NVARCHAR(50) NULL,

[ValidadeCartao] NCHAR(10) NULL,

[CodigoSegurancaCartao] NCHAR(10) NULL,

[Login] NVARCHAR(50) NULL,

[Senha] NVARCHAR(50) NULL,

[Ativo] BIT NULL

)

Relembrando alguns conceitos importantes da modelagem de dados temos que:

Chave Primária - Uma chave primária é utilizada da identificar de forma única cada linha numa tabela.

Chave Externa (Estrangeira)  - Uma chave externa é um campo (ou campos) que aponta para a chave primária de outra tabela.

IDENTITY A propriedade IDENTITY é utilizada para atributos (campos/colunas) das tabelas e tem como objetivo incrementar um valor a cada nova inserção. Assim um campo com a propriedade IDENTITY atribuída como True é um campo autoincremental.

A seguir vou exibir as demais tabelas do banco de dados CiaFilmes.mdf, sua estrutura e o script sql equivalente para geração:

1- Pedidos

CREATE TABLE [dbo].[Pedidos] (

[PedidoId] INT IDENTITY (1, 1) NOT NULL,

[ClienteId] INT NOT NULL,

[PedidoData] DATE NOT NULL,

[QuantidadeTotal] INT NOT NULL,

[ValorPedido] MONEY NOT NULL,

[NumeroPedido] INT NOT NULL,

PRIMARY KEY CLUSTERED ([PedidoId] ASC),

FOREIGN KEY ([ClienteId]) REFERENCES [dbo].[Clientes] ([ClienteId]) ON DELETE CASCADE

);

 

2- PedidosDetalhes

CREATE TABLE [dbo].[PedidosDetalhes] (

[PedidosDetalhesId] INT IDENTITY (1, 1) NOT NULL,

[VideoId] INT NOT NULL,

[Quantidade] INT NOT NULL,

[NumeroPedido] INT NOT NULL,

PRIMARY KEY CLUSTERED ([PedidosDetalhesId] ASC),

CONSTRAINT [FK_PedidosDetalhes_Video] FOREIGN KEY ([VideoId]) REFERENCES [dbo].[Video] ([VideoId])

);

 

3- Filmes

CREATE TABLE [dbo].[Filmes] (
[FilmeId] INT IDENTITY (1, 1) NOT NULL,
[Titulo] NVARCHAR (80) NOT NULL,
[DiretorId] INT NOT NULL,
[ProdutorId] INT NOT NULL,
[Duracao] DECIMAL (10, 2) NOT NULL,
[Descricao] NVARCHAR (250) NOT NULL,
[Categoria] INT NOT NULL,
[AnoLancamento] INT NOT NULL,
PRIMARY KEY CLUSTERED ([FilmeId] ASC),
CONSTRAINT [FK_Filmes_Categorias] FOREIGN KEY ([Categoria]) REFERENCES [dbo].[Categorias] ([CategoriaId]),
CONSTRAINT [FK_Filmes_Produtores] FOREIGN KEY ([ProdutorId]) REFERENCES [dbo].[Produtores] ([ProdutorId]),
CONSTRAINT [FK_Filmes_Diretores] FOREIGN KEY ([DiretorId]) REFERENCES [dbo].[Diretores] ([DiretorId])
);

4- Produtores

CREATE TABLE [dbo].[Produtores] (
    [ProdutoId] INT           IDENTITY (1, 1) NOT NULL,
    [Nome]      NVARCHAR (50) NOT NULL,
    PRIMARY KEY CLUSTERED ([ProdutoId] ASC)
);

5- Diretores

CREATE TABLE [dbo].[Diretores] (
    [DiretorId]  INT           IDENTITY (1, 1) NOT NULL,
    [Nome]       NVARCHAR (50) NOT NULL,
    [Sobrenome]  NVARCHAR (50) NOT NULL,
    [Nascimento] DATE          NOT NULL,
    [Historico]  NVARCHAR(250)   NULL,
    PRIMARY KEY CLUSTERED ([DiretorId] ASC)
);

6- Atores

CREATE TABLE [dbo].[Atores] (
    [AtorId]     INT         IDENTITY (1, 1) NOT NULL,
    [Nome]       NVARCHAR (50) NOT NULL,
    [Sobrenome]  NVARCHAR (50) NOT NULL,
    [Nascimento] DATE          NOT NULL,
    [Historico]  NVARCHAR (250) NULL,
    PRIMARY KEY CLUSTERED ([AtorId] ASC)
);

7- Video

CREATE TABLE [dbo].[Video] (

[VideoId] INT IDENTITY (1, 1) NOT NULL,

[FilmeId] INT NOT NULL,

[Formato] NVARCHAR (50) NOT NULL,

[Preco] MONEY NOT NULL,

PRIMARY KEY CLUSTERED ([VideoId] ASC),

CONSTRAINT [FK_Video_Filmes] FOREIGN KEY ([FilmeId]) REFERENCES [dbo].[Filmes] ([FilmeId])

);

 

8 - AtorFilme

CREATE TABLE [dbo].[AtorFilme] (
[AtorFilmeId] INT IDENTITY (1, 1) NOT NULL,
[AtorId] INT NOT NULL,
[FilmeId] INT NOT NULL,
[Papel] NVARCHAR (50) NOT NULL,
CONSTRAINT [PK_AtorFilme] PRIMARY KEY CLUSTERED ([AtorFilmeId] ASC),
FOREIGN KEY ([FilmeId]) REFERENCES [dbo].[Filmes] ([FilmeId]),
FOREIGN KEY ([AtorId]) REFERENCES [dbo].[Atores] ([AtorId])
);

9- Clientes

CREATE TABLE [dbo].[Clientes] (

[ClienteId] INT IDENTITY (1, 1) NOT NULL,

[Nome] NVARCHAR (50) NULL,

[Sobrenome] NVARCHAR (50) NULL,

[Endereco] NVARCHAR (50) NULL,

[Cidade] NVARCHAR (50) NULL,

[Estado] NCHAR (2) NULL,

[Cep] NCHAR (8) NULL,

[Telefone] NVARCHAR (50) NULL,

[Email] NVARCHAR (100) NULL,

[Nascimento] DATE NULL,

[NumeroCartaoCredito] NVARCHAR (50) NULL,

[ValidadeCartao] NCHAR (10) NULL,

[CodigoSegurancaCartao] NCHAR (10) NULL,

[Login] NVARCHAR (50) NULL,

[Senha] NVARCHAR (50) NULL,

PRIMARY KEY CLUSTERED ([ClienteId] ASC)

);

 

10 - Categorias

CREATE TABLE [dbo].[Categorias] (

[CategoriaId] INT IDENTITY (1, 1) NOT NULL,

[Nome] NVARCHAR (50) NULL,

PRIMARY KEY CLUSTERED ([CategoriaId] ASC)

);

 

Em todas as tabelas foram definidas uma chave primária como sendo do tipo identity. Note que não estamos fazendo um relacionamento entre as tabelas Pedidos e PedidosDetalhes pois estamos usando o número do pedido definidos em ambas as tabelas para fazer esse relacionamento via código.

Abaixo vemos o diagrama de relacionamento entre as tabelas do banco de dados CiaFilmes:

Só para você ter uma ideia abaixo eu coloquei uma imagem de um modelo de dados para uma videolocadora mais próximo da realidade onde temos 20 tabelas.(A modelagem pode variar muito de caso para caso)

Criando a classe Filme

Vamos criar em nosso projeto uma classe Fime que irá representar os filmes. Essa classe será usada apenas para podermos armazenar informações entre as camadas da aplicação, em nosso caso, passar as informações entre os formulários.

Neste momento vamos apresentar alguns conceitos básicos da orientação a objetos aplicados a linguagem VB .NET como Classe, Objeto, etc.

Para criar uma classe no VB .NET você selecione o menu Project (Projeto) - Add Class (Adicionar Classe) ;

Na janela Add New Item (Adicionar novo Item) selecione o template Class (Classe) e informe o nome do arquivo da classe, no caso do VB .NET a extensão será sempre .vb.

Não confunda este arquivo com a classe, este é nome do arquivo no qual você vai criar a classe ou as classes. O nome da classe ou das classes; sim pois um arquivo pode conter mais de uma classe que você informará no interior do arquivo .vb da classe.

No VB .NET podemos resumir a sintaxe usada na declaração de uma classe da seguinte forma:

[ atributo ] [Partial] [ accessibility ] [Shadows] [ inheritance ] _
Class name [(Of type_list )]
       [Inherits classe_pai ]
       [Implements interface ]
       statements
End Class

Para começar podemos dizer que de todas as declarações usadas acima as únicas que são obrigatórias para todas as classes são: a cláusula Class name que identifica uma classe e lhe dá um nome e a declaração End Class que indica o fim da classe. A classe pode ser declarada vazia sem métodos, propriedades ou eventos e mesmo assim continuará válida.

Com base nisso uma classe obrigatoriamente teria que usar no mínimo a seguinte sintaxe ao ser declarada :

Class name
......
End Class

Os valores da declaração de acessibilidade de uma classe podem ser os seguintes: Public , Protected , Friend , Protected Friend ou Private .

Qual a diferença entre classe e objeto ?

Uma das formas você reconhecer a diferença entre uma classe e um objeto (uma instância de uma classe) é fazer uma analogia e considerar a diferença entre tipo e variável do tipo. Vejamos:

Você pode usar o tipo Inteiro ou Integer e uma variável do tipo Integer.

Você não pode atribuir um valor a um tipo , i.e , você não pode fazer a seguinte declaração : Integer = 100

Isto iria gerar um erro.

Mas você pode atribuir um valor a um objeto do tipo Integer :

Dim oInteiro As Integer
oInteiro = 100

Da mesma forma , você não pode atribuir valores a membros em uma classe. Supondo uma classe Carro definida você não pode fazer o seguinte :

Carro.cor  = "vermelho"

pois isto indicaria que todo o carro seria da cor vermelho.

Você teria que definir um objeto da classe para em seguida atribuir uma cor a um objeto da classe. Assim :

Dim meugol As new Carro
Dim meuFord As new Carro

meuGol.cor = "prata"
meuGol.ano = 2003

seuFord.cor = "branco"
seuFord.ano = 2002

Aí sim , você esta definindo objetos específicos da classe carro e atribuindo à propriedade cor o valor "prata" para o objeto meuGol e branco para o objeto meuFord.

Podemos concluir dizendo que :

- A classe Carro tem características (variáveis e métodos) que definem o seu estado como: cor , chassi, placa, ano,  modelo , etc.

- Cada carro (meuGol, seuFord)  - cada instância - tem sua própria combinação de estado : cor, chassi, modelo , ano ,etc.

- A classe seria o modelo pelo qual serão construídas as instâncias da classe (os objetos).(as propriedades cor e ano estão disponíveis para todo objeto criado (instanciado) a partir da classe Carro)

Dessa forma clique no menu PROJECT - Add Class , selecione o template Class e informe o nome Filme.vb.

A seguir digite o código abaixo neste arquivo:

Public Class Filme

    Public Property Id As Integer
    Public Property titulo As String
    Public Property ator As String
    Public Property diretor As String
    Public Property produtor As String

End Class

Definimos assim a classe Filme com 5 propriedades que representam um filme.

Esta classe será usada para representar um filme ou uma coleção de filmes na memória a partir de onde poderemos obter informações dos filmes conforme a consulta solicitada.

Mas onde estão os Sets e os Gets da classe ???

Aqui temos o que chamamos de propriedades autoimplementadas que torna a declaração de propriedades mais concisa quando nenhuma lógica adicional é requerida na propriedade.

Outros exemplos para o VB .NET:

Public Property Nome As String
Public Property Items As New List(Of String) From {"M", "T", "W"}
Public Property ID As New Guid()

Uma propriedade autoimplementada é equivalente a uma propriedade para o qual o valor da propriedade é armazenado em um campo privado.

Na próxima parte do tutorial iremos abordar os conceitos básicos da ADO .NET, a tecnologia para acesso e persistência de dados da Microsoft, que iremos usar em nosso projeto.

Referências:


José Carlos Macoratti