Usando MySql com ADO.NET Entity Framework 4 - Parte I

Este é o primeiro artigo de cinco partes, explicando os como utilizar Mysql com o ADO.NET Entity Framework 4 no Visual Studio 2010 em C#. Usando modelo de três camadas com orientação a objetos.

O Entity Framework (EF4) faz parte da família de tecnologias do ADO.NET oferecem o mapeamento objeto relacional (OR/M) a um nível conceitual de abstração. O EF4 possui novas funcionalidades e melhorias, as quais foram sugeridas por muitos desenvolvedores desde a versão 1.0. Desta forma, possibilitou "aproximar" de algumas características oferecidas em outras ferramentas de mapeamento objeto relacional, como NHibernate. As ferramentas de mapeamento objeto-relacional são usadas para eliminar grande parte do código tedioso necessário para recuperar e persistir dados de um banco de dados.

Através de uma interface visual, o desenvolvedor usa-a para criar classes que são mapeadas para tabelas, relacionamentos, stored procedures e outros objetos em um banco de dados. Uma das grandes novidades do EF4 é a capacidade de criar um ADO.NET Entity Data Model e então construir a base de dados a partir do modelo. Anteriormente, o desenvolvedor precisava criar o banco de dados e depois gerar o modelo.

Sendo assim, o objetivo deste artigo é mostrar como fazer o mapeamento e CRUD com Entity Framework 4 partindo de um banco de dados em MySQL, já que a maioria dos artigos mostram como fazer o mapeamento com o banco de dados SQL Server. E construir uma simples aplicação utilizando-se das três camadas e a linguagem C#.

Requerimentos

Iniciaremos nosso exemplo criando uma database com o nome de BDEntity, como mostra a Figura 1.

Figura 1. Diagrama de banco de dados

Projeto

Para o nosso projeto será utilizado o modelo de três camadas, como descrito abaixo:

No Visual Studio 2010 selecione File | New | Project. No dropdown selecione o .NET Framework 4, em Installed Templates | Web escolha Empty ASP.NET Web Application. Preencha o campo Name com AppEntity e mantenha a opção “Create directory for solution” selecionada e clique em OK. Conforme traz a Figura 2.

Figura 2. Iniciando projeto

Na Solution Explorer, a camada UI já está adicionada ao projeto, já que escolhemos o template ASP.NET web application.

Então, adicione dois novos projetos do tipo Class Library dentro da solução. Para fazer isso, com o botão direito sobre a Solution Explorer e depois em Add | New Project, será apresentada uma tela como mostra a Figura 3.

Então selecione o template Windows | Class Library.

No campo Name, preencha com os nomes de Entity.Bll e Entity.Dal respectivamente.

Figura 3. Adicionando projetos para a camada de negócios e dados

A solução deverá possuir três projetos como mostra a Figura 4.

Figura 4 - Solução com três projetos

A camada de acesso a dados (DAL)

No projeto Entity.DAL será utilizado o Entity Data Model com base em nosso modelo de dados. Clique com o botão direito sobre o projeto Entity.DAL e selecione Add |New Item. A seguir selecione o template Data | ADO .NET Entity Data Model , informe o nome model.edmx e clique no botão Add. A Figura 5 traz a demonstração.

Figura 5 - Adicionando Modelo Entity Data Model

A seguir, é mostrado um assistente que permite escolher dentre duas opções, tais como Generate from database e Empty Model. A primeira opção permite criar o mapeamento a partir do banco de dados, e a segunda permite criar um modelo de dados e então criar o script necessário para construir a base de dados. A Figura 6 mostra as duas opções.

Figura 6 - Opções para modelo de dados

Então, selecione a opção Generate from database e em seguida pressione Next. Após, selecione a conexão com o banco de dados, como mostra a Figura 7, e clique em Next.

Figura 7. Conexão com banco de dados
Nota: Para configurar a conexão com o banco de dados clique em New Connection.

Em seguida selecione as tabelas e aceite o nome do Namespace como testModel, como traz a Figura 8 e clique em Finish.

Figura 8 - Adicionando tabelas para o modelo

Por fim, como mostra a Figura 9, as entidades foram criadas e o mapeamento ORM gerado automaticamente pela ferramenta.

Figura 9 - Entidades e mapeamento

Na Figura 9 é possível observar as entidades, tbsecao, tbcategoria e tbproduto criadas, bem como o mapeamento em Mapping Details . O arquivo Model.edmx possui um arquivo associado que foi gerado automaticamente pelo Entity. Abra o arquivo associado ModelDesigner.cs e veja o comentário adicionado, como mostra a Figura 10. Esta mensagem indica que o arquivo foi gerado automaticamente pelo template e modificações manuais podem causar comportamento inesperado, bem como a perda de informações caso o modelo seja gerado novamente pelo Entity Data Model.

Figura 10 - Comentário de aviso

A partir disso, é necessário definir alguns métodos para cada entidade. Para isso, será criada uma Interface. E a seguir, uma classe abstrata que implementa esta interface. E consequentemente, devemos criar as classe concretas das entidades tbsecao, tbcategoria e tbproduto que herdam a classe abstrata.

A criação do mapeamento relacional a partir da existência de uma base de dados, a criação da estrutura para um projeto em três camadas. Sendo assim, a partir do que foi explicado, podemos começar com a criação das Interfaces, Classes e métodos responsáveis pela camada de acesso DAL. Antes de começar com a definição dos métodos, queria mostrar a User Interface que iremos criar ao decorrer dos artigos, pois temos que saber onde iremos chegar com estes tutorias, não é mesmo? A Figura 11 traz a interface administrativa do nosso sistema.

Figura 11 - User Interface Administrativa

Definição dos métodos no projeto Entity.DAL

A criação de um projeto bem organizado e com comentários facilita em manutenções posteriores. Para tanto vamos começar na criação de folders e Interfaces. Crie um folder com nome de Interfaces e dentro do folder interfaces, crie duas interfaces ICrud.cs e IID.cs que conterá as assinaturas dos métodos.

Nota: Clique com o botão direito sobre o folder interfaces e selecione Add |New Item. A seguir selecione o template Code | Interface e informe o nome ICrud.cs e clique em Add. Faça o mesmo para a interface IID.cs

1- No arquivo ICrud.cs defina do código, como mostrado na Listagem 1.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Objects.DataClasses; using System.Linq.Expressions; namespace Entity.DAL.Interfaces { public interface ICrud<T> where T: EntityObject, Interfaces.IID { bool Create(T entity); bool Update(T entity); bool Delete(int id, T entity); T GetByID(int id, T entity); IQueryable<T> ALL(); } }
Listagem 1. Definição dos métodos CRUD

A interface ICrud é fortemente tipada e está recebendo como parâmetro uma entidade, onde T é do tipo EntityObject , ou seja, pode-se usar como parâmetro qualquer Entidade do modelo criado. Ainda sim, deve-se herdar a interface IID, que será usada pelos métodos. Você deve estar curioso para saber o porquê de herdar a interface IID. A interface IID foi criada com o objeto de trabalhar com a propriedade ID de cada entidade. Por seguinte, podemos definir os principais métodos para a manipulação no banco de dados. 2-) Definição do código no arquivo IID.cs, como mostrado na Listagem 2.

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Entity.DAL.Interfaces { public interface IID { Int32 ID { get; } } }
Listagem 2. Definição da propriedade ID

Também, no código da Interface foi adicionado dois Namespaces.

3-) A partir disso, será necessário criar uma classe abstrata que irá implementar a Interface ICrud.cs.

Clique com o botão direito sobre o projeto Entity.DAL e selecione Add |New Item. A seguir selecione o template Code | Class e informe o nome Crud.cs e clique em Add.

4-) Definição do código no arquivo Crud.cs, como mostrado na Listagem 3.

namespace Entity.DAL { public abstract class Crud<T> : Interfaces.ICrud<T> where T : EntityObject, Interfaces.IID { //criando uma estancia do contexto definido pelo Entity Data Model //no arquivo Model.Edmx private testEntities context = new testEntities(); public bool Create(T entity) { try { context.AddObject(entity.GetType().Name, entity); context.SaveChanges(); return true; } catch { return false; } } public bool Update(T entity) { try { context.ApplyCurrentValues<T>(entity.GetType().Name, entity); return true; } catch { return false; } } public IQueryable<T> ALL() { return context.CreateObjectSet<T>(); } public bool Delete(int id, T entity) { try { var _entity = this.GetByID(id,entity); context.DeleteObject(_entity); context.SaveChanges(); return true; } catch { return false; throw; } } public T GetByID(int id, T entity) { string tablename = entity.GetType().Name; return context.CreateQuery<T>(tablename).Where (q => q.ID == id).FirstOrDefault(); } } }
Listagem 3. Implementando métodos de manipulação

No código apresentado na Listagem 3 foi criado uma estância do contexto definido pelo Entity Data Model no arquivo Model.Edmx. Você pode observar o nome na propriedade, como mostra a Figura 12.

Figura 12 - Propriedade Entity Container Name

A expressão Where(q => q.ID == id) dentro do método GetByID, só é possível porque utilizamos herança.

5-) Criar três classes partial com os nomes de tbsecao, tbcategoria e tbproduto. Estas classes deveram herdar a Interface IID, como mostrado nas Listagens 4, 5 e 6.

namespace Entity.DAL { public partial class tbcategoria : Interfaces.IID { } }
Listagem 4. Classe Partial tbcategoria
namespace Entity.DAL { public partial class tbproduto : Interfaces.IID { } }
Listagem 5. Classe Partial tbproduto
namespace Entity.DAL { public partial class tbsecao : Interfaces.IID { } }
Listagem 6. Classe Partial tbsecao

Estas classes devem ter o mesmo nome das classes partial que estão dentro do arquivo Model.Designer.cs. Poderíamos colocar a herança dentro das classes que estão dentro do Model.Designer, porém caso o modelo seja gerado novamente poderá ocorrer perda de informações. O próximo passo é criar as três classes concretas SecaoData, CategoriaData e ProdutoData, como traz as Listagens 7, 8 e 9.

namespace Entity.DAL { public class SecaoData : Crud<tbsecao> { //criando uma instancia do contexto definido pelo //Entity Data Model no arquivo Model.Edmx private testEntities context = new testEntities(); public tbsecao GetSecao() { tbsecao _secao = new tbsecao(); return _secao; } public IQueryable<tbsecao> Filter(string _filter) { IQueryable<tbsecao> _tbsecao = null; try { _tbsecao = context.tbsecao.Where(s => s.TITULO.IndexOf(_filter) > -1); return _tbsecao; } catch { return _tbsecao = null; } } } }
Listagem 7. Classe concreta SecaoData
namespace Entity.DAL { public class CategoriaData : Crud<tbcategoria> { } }
Listagem 8. Classe concreta CategoriaData
namespace Entity.DAL { public class ProdutoData: Crud<tbproduto> { } }
Listagem 9. Classe concreta ProdutoData

Artigos relacionados