7. Estudo de caso com o Firebird 2.1
7.1. Instalação das ferramentas
As ferramentas a instalar são as seguintes:
- o SGBD: [http://www.firebirdsql.org/en/firebird-2-1-5/];
- uma ferramenta de administração: EMS SQL Manager for InterBase/Firebird Freeware [http://www.sqlmanager.net/fr/products/ibfb/manager/download].
Nos exemplos a seguir, o utilizador é sysdba com a palavra-passe masterkey.
Vamos iniciar o Firebird e, em seguida, a ferramenta [SQL Manager Lite for Firebird], que utilizaremos para administrar o SGBD.
![]() |
- Em [1], iniciamos o SGBD Firebird a partir do Menu Iniciar. Aqui, o SGBD não foi instalado como um serviço do Windows;
- em [2], o serviço é iniciado. Aparece um ícone no canto inferior direito do ecrã. Ao clicar com o botão direito do rato nesse ícone, pode parar o SGBD.
Iniciamos agora a ferramenta [SQL Manager Lite for Firebird], que utilizaremos para administrar o SGBD [3].
![]() |
- Em [4], criamos uma nova base de dados;
- Em [5], confirmamos;
![]() |
- Em [5], iniciamos sessão como SYSDBA / masterkey;
- Em [6], especifique a localização do ficheiro a ser criado. A base de dados será criada como um único ficheiro;
- Em [7], validamos a instrução SQL a ser executada;
![]() |
- Em [8], a base de dados foi criada. Agora, deve ser registada no [EMS Manager]. As informações estão corretas. Clique em [OK];
- Em [9], inicie sessão;
- Em [10], o [EMS Manager] apresenta a base de dados, que está atualmente vazia.
Vamos agora ligar um projeto VS 2012 a esta base de dados.
7.2. Criação da base de dados a partir das entidades
Começamos por duplicar a pasta do projeto [RdvMedecins-SqlServer-01] para [RdvMedecins-Firebird-01] [1]:
![]() |
- em [2], no VS 2012, removemos o projeto [RdvMedecins-SqlServer-01] da solução;
![]() |
- em [3], o projeto foi removido;
- em [4], adicionamos outro. Este foi retirado da pasta [RdvMedecins-Firebird-01] que criámos anteriormente;
![]() |
- Em [5], o projeto carregado tem o nome [RdvMedecins-SqlServer-01];
- Em [6], alteramos o seu nome para [RdvMedecins-Firebird-01]
![]() |
- em [7], adicionamos outro projeto à solução. Este projeto é retirado da pasta [RdvMedecins-SqlServer-01] do projeto que removemos anteriormente da solução;
- em [8], o projeto [RdvMedecins-SqlServer-01] foi novamente adicionado à solução.
O projeto [RdvMedecins-Firebird-01] é idêntico ao projeto [RdvMedecins-SqlServer-01]. Precisamos de fazer algumas alterações. Em [App.config], iremos modificar a cadeia de ligação e o [DbProviderFactory], que devem ser adaptados para cada SGBD.
<!-- connection chain on base -->
<connectionStrings>
<add name="monContexte" connectionString="User=SYSDBA;Password=masterkey;Database=D:\data\istia-1213\c#\dvp\Entity Framework\databases\firebird\RDVMEDECINS-EF.GDB;DataSource=localhost;
Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;" providerName="FirebirdSql.Data.FirebirdClient" />
</connectionStrings>
<!-- the factory provider -->
<system.data>
<DbProviderFactories>
<add name="Firebird Client Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".Net Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient, Version=2.7.7.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
</DbProviderFactories>
</system.data>
- linha 3: o nome de utilizador e a palavra-passe, bem como o caminho completo para a base de dados Firebird;
- Linhas 8–10: o DbProviderFactory. A linha 9 faz referência a uma DLL [FirebirdSql.Data.FirebirdClient] que não temos. Podemos obtê-la utilizando o NuGet [1]:
![]() |
- em [2], digite a palavra-chave «firebird» na caixa de pesquisa;
- em [3], selecione o pacote [Firebird ADO.NET Data Provider]. Trata-se de um conector ADO.NET para o Firebird;
![]() |
- em [4], a nova referência;
- em [5], em [App.config], deve especificar a versão correta da DLL. Pode encontrá-la nas suas propriedades.
No ficheiro [Entities.cs], é necessário adaptar o esquema das tabelas que serão geradas:
[Table("MEDECINS")]
public class Medecin : Personne
{...}
[Table("CLIENTS")]
public class Client : Personne
{...}
[Table("CRENEAUX")]
public class Creneau
{...}
[Table("RVS")]
public class Rv
{...}
Aqui, as tabelas não têm esquema.
Configuramos a execução do projeto:
![]() |
- em [1], atribuímos um nome diferente ao assembly que será gerado;
- em [2], especificamos também um namespace padrão diferente;
- em [3], especificamos o programa a ser executado.
Nesta fase, não há erros de compilação. Vamos executar o programa [CreateDB_01]. Recebemos a seguinte exceção:
Recordamos ter encontrado o mesmo erro com o MySQL, o Oracle e o PostgreSQL. Isto está relacionado com o tipo do campo Timestamp nas entidades. Fazemos a mesma modificação que com os dois SGBDs anteriores. Nas entidades, substituímos as três linhas
[Column("TIMESTAMP")]
[Timestamp]
public byte[] Timestamp { get; set; }
com o seguinte:
[ConcurrencyCheck]
[Column("VERSIONING")]
public int? Versioning { get; set; }
Por isso, alteramos o tipo da coluna de byte[] para int?. No SGBD, utilizaremos procedimentos armazenados para incrementar este inteiro em um cada vez que uma linha for inserida ou modificada.
Efetamos a alteração acima em todas as quatro entidades e, em seguida, executamos novamente a aplicação. Recebemos então o seguinte erro:
A linha 1 indica que a base de dados está em uso. Não creio que fosse esse o caso e não consegui resolver este problema.
Não importa. Vamos criar a base de dados [RDVMEDECINS-EF] manualmente utilizando a ferramenta [EMS Manager for Firebird]. Não descreveremos todos os passos, mas apenas os mais importantes.
A base de dados Firebird terá a seguinte estrutura:
As tabelas
![]() |
- Em [1],
IDé uma chave primária com o atributo</span>*Autoincrement*. Será gerada automaticamente pelo SGBD;
![]() |
![]() |
![]() |
As várias tabelas têm as mesmas chaves primárias e estrangeiras que as dos exemplos anteriores. As chaves estrangeiras têm o atributo ON DELETE CASCADE.
Os geradores
Tal como no Oracle e no PostgreSQL, criámos geradores de números sequenciais. Existem 5 deles [1].
![]() |
- [CLIENTS_ID_GEN] será utilizado para gerar a chave primária da tabela [CLIENTS];
- [MEDECINS_ID_GEN] será utilizado para gerar a chave primária da tabela [MEDECINS];
- [CRENEAUX_ID_GEN] será utilizado para gerar a chave primária da tabela [CRENEAUX];
- [RVS_ID_GEN] será utilizado para gerar a chave primária da tabela [RVS];
- [VERSIONS_GEN] será utilizado para gerar os valores das colunas [VERSIONING] em todas as tabelas.
Gatilhos
Um gatilho é um procedimento executado pelo SGBD antes ou depois de um evento (Insert, Update, Delete) numa tabela. Temos 8 deles [1]:
![]() |
Vejamos o código DDL do trigger [BI_CLIENTS_ID], que preenche a coluna [ID] da tabela [CLIENTS]:
- Linha 2: Antes de cada inserção na tabela [CLIENTS];
- linhas 6-7: se a coluna ID for NULL, atribua-lhe o valor seguinte do gerador de números [CLIENTS_ID_GEN].
Os gatilhos [BI_CLIENTS_ID, BI_MEDECINS_ID, BI_CRENEAUX_ID, BI_RVS_ID] são todos construídos da mesma forma.
Vejamos agora o código DDL do gatilho [CLIENTS_VERSION_TRIGGER], que preenche a coluna [VERSIONING] da tabela [CLIENTS]:
- Linhas 1–3: Antes de cada operação INSERT ou UPDATE na tabela [CLIENTS];
- linha 6: a coluna ["VERSIONING"] recebe o valor seguinte do gerador de números [VERSIONS_GEN]. Este gerador preenche as colunas ["VERSIONING"] das quatro tabelas.
Os gatilhos [MEDECINS_VERSION_TRIGGER, CRENEAUX_VERSION_TRIGGER, RVS_VERSION_TRIGGER] são semelhantes.
O script para gerar as tabelas na base de dados Firebird [RDVMEDECINS-EF] foi colocado na pasta [RdvMedecins / databases / Firebird]. O leitor pode carregá-lo e executá-lo para criar as tabelas.
Depois de feito isso, os vários programas do projeto podem ser executados. Eles produzem os mesmos resultados que no SQL Server, exceto o programa [ModifyDetachedEntities], que falha pelo mesmo motivo que falhou com o Oracle e o MySQL. O problema é resolvido da mesma forma. Basta copiar o programa [ModifyDetachedEntities] do projeto [RdvMedecins-Oracle-01] para o projeto [RdvMedecins-Firebird-01].
7.3. Arquitetura multicamadas baseada no EF 5
Voltamos ao nosso estudo de caso descrito no parágrafo 2.
![]() |
Começaremos por construir a camada de acesso aos dados [DAO]. Para tal, duplicamos o projeto de consola do VS 2012 [RdvMedecins-SqlServer-02] para [RdvMedecins-Firebird-02] [1]:
![]() |
- em [2], eliminamos o projeto [RdvMedecins-SqlServer-02];
![]() |
- em [3], adicionamos um projeto existente à solução. Retirámo-lo da pasta [RdvMedecins-Firebird-02] que acabámos de criar;
- em [4], o novo projeto tem o mesmo nome que o que foi eliminado. Vamos alterar o seu nome;
![]() |
- Em [5], alterámos o nome do projeto;
- Em [6], modificamos algumas das suas propriedades, como o nome do conjunto;
- em [7], a pasta [Models] é eliminada e substituída pela pasta [Models] do projeto [RdvMedecins-Firebird-01]. Isto deve-se ao facto de ambos os projetos partilharem os mesmos modelos.
![]() |
- em [8], as referências atuais do projeto;
- Em [9], o conector Firebird ADO.NET foi adicionado utilizando a ferramenta NuGet.
No ficheiro [App.config], substitua as informações da base de dados SQL Server pelas da base de dados Firebird. Estas informações podem ser encontradas no ficheiro [App.config] do projeto [RdvMedecins-Firebird-01]:
<!-- connection chain on base -->
<connectionStrings>
<add name="monContexte" connectionString="User=SYSDBA;Password=masterkey;Database=D:\data\istia-1213\c#\dvp\Entity Framework\databases\firebird\RDVMEDECINS-EF.GDB;DataSource=localhost;
Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;" providerName="FirebirdSql.Data.FirebirdClient" />
</connectionStrings>
<!-- the factory provider -->
<system.data>
<DbProviderFactories>
<add name="Firebird Client Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".Net Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient, Version=2.7.7.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
</DbProviderFactories>
</system.data>
Os objetos geridos pelo Spring também mudam. Atualmente, temos:
<!-- spring configuration -->
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object id="rdvmedecinsDao" type="RdvMedecins.Dao.Dao,RdvMedecins-SqlServer-02" />
</objects>
</spring>
A linha 7 faz referência ao assembly do projeto [RdvMedecins-SqlServer-02]. O assembly é agora [RdvMedecins-Firebird-02].
Feito isso, estamos prontos para executar o teste da camada [DAO]. Primeiro, temos de garantir que a base de dados está preenchida (utilizando o programa [Fill] do projeto [RdvMedecins-Firebird-01]). O programa de teste é bem-sucedido.
Criamos a DLL do projeto tal como fizemos para o projeto [RdvMedecins-SqlServer-02] e reunimos todas as DLLs do projeto numa pasta [lib] criada em [RdvMedecins-Firebird-02]. Estas serão as referências para o projeto web [RdvMedecins-Firebird-03] que se segue.
![]() |
Estamos agora prontos para criar a camada [ASP.NET] da nossa aplicação:
![]() |
Começaremos pelo projeto [RdvMedecins-SqlServer-03]. Iremos duplicar esta pasta do projeto para [RdvMedecins-Firebird-03] [1]:
![]() |
- em [2], utilizando o VS 2012 Express for the Web, abrimos a solução na pasta [RdvMedecins-Firebird-03];
- em [3], alteramos tanto o nome da solução como o nome do projeto;
![]() |
- em [4], as referências atuais do projeto;
- em [5], eliminamo-las;
- em [6], para as substituir por referências às DLLs que acabámos de guardar numa pasta [lib] dentro do projeto [RdvMedecins-Firebird-02].
Resta apenas modificar o ficheiro [Web.config]. Substituímos o seu conteúdo atual pelo conteúdo do ficheiro [App.config] do projeto [RdvMedecins-Firebird-02]. Depois de feito isto, executamos o projeto web. Funciona. Não se esqueça de preencher a base de dados antes de executar a aplicação web.

























