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.Projeto
Para o nosso projeto será utilizado o modelo de três camadas, como descrito abaixo:
- BLL - (Business Logic Layer) responsável pela lógica do negócio;
- DAL - (Data Access Layer) responsável pelo acesso e persistência dos dados - interface e classes de acesso a dados usando o Entity Framework;
- UI - (User Interface) responsável pela interface com o usuário - Aplicação WEB.
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.
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.
A solução deverá possuir três projetos como mostra a Figura 4.
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.
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.
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.
Em seguida selecione as tabelas e aceite o nome do Namespace como testModel, como traz a Figura 8 e clique em Finish.
Por fim, como mostra a Figura 9, as entidades foram criadas e o mapeamento ORM gerado automaticamente pela ferramenta.
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.
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.
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.
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();
}
}
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; }
}
}
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();
}
}
}
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.
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
{
}
}
namespace Entity.DAL
{
public partial class tbproduto : Interfaces.IID
{
}
}
namespace Entity.DAL
{
public partial class tbsecao : Interfaces.IID
{
}
}
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; }
}
}
}
namespace Entity.DAL
{
public class CategoriaData : Crud<tbcategoria>
{
}
}
namespace Entity.DAL
{
public class ProdutoData: Crud<tbproduto>
{
}
}