Ir para o conteúdo
Criar ASP.NET API Web com a Abordagem do Entity Framework Code First e o Padrão de Repositório

Criar ASP.NET API Web com a Abordagem do Entity Framework Code First e o Padrão de Repositório

Neste artigo, aprenderemos a criar uma API Web ASP.NET usando o padrão Repository e a abordagem code first do Entity Framework.

10min read

Neste artigo, aprenderemos a criar uma API Web ASP.NET usando o padrão Repository e a abordagem code first do Entity Framework.

Essencialmente, você aprenderá como:

  1. Criar um projeto principal que conterá a entidade e a interface do repositório;
  2. Crie um projeto de infraestrutura que conterá o código de operações de banco de dados usando a abordagem de código primeiro do Entity Framework;
  3. Crie uma API Web para executar operações CRUD na entidade;
  4. Consuma a API Web em um aplicativo jQuery e renderize os dados no Ignite UI Chart.

O que é um padrão de repositório?

Vamos primeiro entender por que precisamos de um padrão de repositório. Se você não seguir um padrão de repositório e usar diretamente os dados, os seguintes problemas podem surgir:

  • Duplicate code
  • Dificuldade em implementar qualquer lógica ou política relacionada a dados, de modo que o armazenamento em cache
  • Dificuldade em testar a lógica de negócios sem ter a camada de acesso a dados
  • Lógica de negócios fortemente acoplada e lógica de acesso ao banco de dados

Ao implementar um padrão de repositório, podemos evitar os problemas acima e obter as seguintes vantagens:

  • A lógica de negócios pode ser testada por unidade sem lógica de acesso a dados
  • O código de acesso ao banco de dados pode ser reutilizado
  • O código de acesso ao banco de dados é gerenciado centralmente, de modo que é fácil implementar qualquer política de acesso ao banco de dados, de modo que o armazenamento em cache
  • Lógicas de domínio fáceis de implementar
  • Entidades de domínio ou entidades de negócios são fortemente tipadas com as anotações.

Agora que listamos como eles são ótimos, vamos começar a implantar um padrão de repositório na API Web ASP.NET.

Criar o projeto principal

No projeto principal, você deve manter as entidades e as interfaces do repositório. Neste exemplo, vamos trabalhar com a entidade City. Então, vamos criar uma cidade de classe, conforme mostrado na lista abaixo:

using System.ComponentModel.DataAnnotations;
 
namespace WebApiRepositoryPatternDemo.Core.Entities
{
   public class City
    {
       public int Id { get; set; }
       [Required]
       public string Name { get; set; }
       public string Country { get; set; }
       public int Population01 { get; set; }
       public int Population05 { get; set; }
       public int Population10 { get; set; }
       public int Population15 { get; set; }
    }
}

Como você pode ver, estamos anotando dados usando o atributo Required, que faz parte de System.ComponentModel.DataAnnotations. Podemos colocar anotações na entidade da cidade usando uma das duas abordagens:

  1. Usando o System.ComponentModel.DataAnnotations
  2. Using the Entity Framework Fluent API

Ambas as abordagens têm suas próprias vantagens. Se você considerar que a restrição nas entidades de domínio faz parte do domínio, use anotações de dados no projeto principal. No entanto, se você considerar que as restrições estão relacionadas ao banco de dados e usar a estrutura de entidade como tecnologia de banco de dados, opte por uma API fluente.

Em seguida, vamos criar a interface do repositório. Qualquer operação que você queira executar na entidade City deve fazer parte da interface do repositório.  A interface ICityRepository pode ser criada conforme mostrado na listagem abaixo:

using System.Collections.Generic;
using WebApiRepositoryPatternDemo.Core.Entities;
 
namespace WebApiRepositoryPatternDemo.Core.Interfaces
{
    public interface ICityRepository
    {
        void Add(City b);
        void Edit(City b);
        void Remove(string Id);
        IEnumerable<City> GetCity();
        City FindById(int Id);
    }
}

Lembre-se de que o projeto principal nunca deve conter nenhum código relacionado a operações de banco de dados. Portanto, as seguintes referências não devem fazer parte do projeto principal-

  • Referência a qualquer biblioteca externa
  • Referência a qualquer biblioteca de banco de dados
  • Referência a qualquer ORM como LINQ to SQL, entity framework, etc.

Depois de adicionar a classe de entidade e a interface do repositório, o projeto principal deve se parecer com a imagem abaixo:

Adicionando a classe de entidade e a interface do repositório, o projeto principal deve se parecer com a imagem

Criar o projeto de infraestrutura

No projeto de infraestrutura, realizamos operações que estão relacionadas a fora da aplicação. Por exemplo:

  • Database operations
  • Consumindo serviços da Web
  • Acessando sistemas de arquivos

Para executar a operação de banco de dados, usaremos a abordagem do Entity Framework Code First. Lembre-se de que já criamos a entidade da cidade na qual as operações CRUD precisam ser executadas. Essencialmente, para habilitar operações CRUD, as seguintes classes são necessárias:

  • DataContext class
  • Classe de repositório implementando Interface de repositório criada no projeto principal
  • DataBaseInitalizer class

Em seguida, precisamos adicionar as seguintes referências no projeto de infraestrutura:

  • Uma referência da estrutura Entity. Para adicionar isso, clique com o botão direito do mouse no projeto e clique em gerenciar pacote Nuget e, em seguida, instale a estrutura da entidade
  • Uma referência do projeto principal

DataContext class

 In the DataContext class:

  1. Crie uma propriedade DbSet que criará a tabela para a entidade City
  2. No construtor da classe DataContext, passe o nome da cadeia de conexão em que o banco de dados seria criado
  3. CityDataContext class will inherit the DbContext class

A classe CityDataContext pode ser criada conforme mostrado na listagem abaixo:

using System.Data.Entity;
using WebApiRepositoryPatternDemo.Core.Entities;
 
namespace WebApiRepositoryPatternDemo.Infrastructure
{
   public class CityDataContext : DbContext
   {
       public CityDataContext() : base("name=cityconnectionstring")
       {
 
       }
       public IDbSet<City> Cities { get; set;  }
 
    }
}

Opcionalmente, você pode passar a cadeia de conexão ou contar com o Entity Framework para criar o banco de dados. Configuraremos a cadeia de conexão em app.config do projeto de infraestrutura. Vamos em frente e definir a cadeia de conexão, conforme mostrado na lista abaixo:

  <connectionStrings>
  <add name="cityconnectionstring" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=CityPolulation;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
  </connectionStrings>

Classe de inicialização do banco de dados

Precisamos criar uma classe de inicialização de banco de dados para alimentar o banco de dados com algum valor inicial no momento da criação.  Para criar a classe de inicialização do banco de dados, crie uma classe e herde-a de DropCreateDatabaseIfModelChnages. Aqui, estamos definindo o valor para que, se o modelo for alterado, recrie o banco de dados. Também podemos explorar as outras opções da estrutura de entidade e herdar a classe initialize do banco de dados da classe cross ponding.  No método Seed, podemos definir o valor inicial para a tabela Cities. Com um registro de três cidades, a classe do inicializador do banco de dados pode ser criada conforme mostrado na listagem abaixo:

using System.Data.Entity;
using WebApiRepositoryPatternDemo.Core.Entities;

namespace WebApiRepositoryPatternDemo.Infrastructure {
    public class CityDbInitalize : DropCreateDatabaseIfModelChanges<CityDataContext> {

        protected override void Seed(CityDataContext context) {
            context.Cities.Add(new City {
                    Id=1,
                    Country="India",
                    Name="Delhi",
                    Population01=20,
                    Population05=22,
                    Population10=25,
                    Population15=30
                });

            context.Cities.Add(new City {
                    Id=2,
                    Country="India",
                    Name="Gurgaon",
                    Population01=10,
                    Population05=18,
                    Population10=20,
                    Population15=22
                });

            context.Cities.Add(new City {
                    Id=3,
                    Country="India",
                    Name="Bangalore",
                    Population01=8,
                    Population05=20,
                    Population10=25,
                    Population15=28
                });

            context.SaveChanges();

            base.Seed(context);

        }
    }
}

Repository class

Até agora, criamos as classes DataContext e DatabaseInitalize. Usaremos a classe DataContext na classe repository. A classe CityRepository implementará a interface ICityRepository do projeto principal e executará operações CRUD usando a classe DataContext. A classe CityRepository pode ser implementada conforme mostrado na listagem abaixo:

using System.Collections.Generic;
using System.Linq;
using WebApiRepositoryPatternDemo.Core.Entities;
using WebApiRepositoryPatternDemo.Core.Interfaces;
 
namespace WebApiRepositoryPatternDemo.Infrastructure.Repository
{
    public class CityRepository : ICityRepository
    {
        CityDataContext context = new CityDataContext();
        public void Add(Core.Entities.City b)
        {
            context.Cities.Add(b);
            context.SaveChanges();          
        }
 
        public void Edit(Core.Entities.City b)
        {
            context.Entry(b).State = System.Data.Entity.EntityState.Modified;
        }
 
        public void Remove(string Id)
        {
            City b = context.Cities.Find(Id);
            context.Cities.Remove(b);
            context.SaveChanges();
        }
 
        public IEnumerable<Core.Entities.City> GetCity()
        {
            return context.Cities;
        }
 
        public Core.Entities.City FindById(int Id)
        {
            var c = (from r in context.Cities where r.Id == Id select r).FirstOrDefault();
            return c;
        }
    }
}

A implementação da classe CityRepository é muito simples. Você pode ver que estamos usando o código LINQ to Entity usual para executar as operações CRUD. Após a implementação de todas as classes, o projeto de infraestrutura deve ficar parecido com a imagem abaixo:

Depois de implementar todas as classes, o projeto de infraestrutura deve se parecer com a imagem

Create the WebAPI project

Agora vamos criar o projeto da API Web. Para começar, precisamos adicionar as seguintes referências:

  1. Referência do projeto principal
  2. Referência do projeto de infraestrutura
  3. Referência da estrutura de entidade

Depois de adicionar todas as referências no projeto da API Web, copie a cadeia de conexão (adicionada na etapa anterior cityconnectionstring) do APP. Configuração do projeto de infraestrutura para o web.config do projeto de API Web.  Em seguida, abra o arquivo Global.asax e, no método Application_Start(), adicione as linhas de código abaixo para garantir que os dados de semente tenham sido inseridos no banco de dados:

CityDbInitalize db = new CityDbInitalize();
System.Data.Entity.Database.SetInitializer(db);

Neste ponto, crie o projeto da API Web e clique com o botão direito do mouse na pasta Controladores e em um novo controlador. Crie um novo controlador com o scaffolding, escolhendo Web API 2 Controller com ações, usando a opção Entity Framework conforme mostrado na imagem abaixo:

add scaffold window

Em seguida, para adicionar o Controller, selecione a classe City como a classe Model e a classe CityDataContext como a classe de contexto Data.

add controller window

Depois de clicar em Adicionar, você verá que um controlador de API Web foi criado com o nome CitiesController na pasta Controllers. Neste ponto, quando você executar a API Web, deverá ser capaz de OBTER as Cidades no navegador, conforme mostrado na imagem abaixo:

Neste ponto, quando você for em frente e executar a API Web, você deve ser capaz de OBTER as cidades no navegador, como mostrado na imagem

Aqui, criamos a API Web usando a abordagem CodeFirst do Entity Framework e o padrão Repository.  Você pode executar operações CRUD executando operações POST, GET, PUT e DELETE na URL da api/cities.

JQuery Client to consume Web API

Agora vamos em frente e exibir a população das cidades em um igChart. Eu adicionei referências dos arquivos IgniteUI JS e CSS no HTML, conforme mostrado na listagem abaixo:

<title>igGrid CRUD Demo</title>
    <link href="Content/Infragistics/css/themes/infragistics/infragistics.theme.css" rel="stylesheet" />
    <link href="Content/Infragistics/css/structure/infragistics.css" rel="stylesheet" />
    <link href="Content/bootstrap.min.css" rel="stylesheet" />
 
    <script src="Scripts/modernizr-2.7.2.js"></script>
    <script src="Scripts/jquery-2.0.3.js"></script>
    <script src="Scripts/jquery-ui-1.10.3.js"></script>
 
    <script src="Scripts/Infragistics/js/infragistics.core.js"></script>
    <script src="Scripts/Infragistics/js/infragistics.dv.js"></script>
    <script src="Scripts/Infragistics/js/infragistics.lob.js"></script>
 
 
    <script src="Scripts/demo.js"></script>

No elemento Corpo, adicionei uma tabela conforme mostrado na listagem abaixo:

<table>
    <tr>
        <td id="columnChart" class="chartElement"></td>
        <td id="columnLegend" style="float: left"></td>
    </tr>
</table>

Para converter a tabela para o igChart na função de documento pronto do jQuery, precisamos selecionar a tabela e convertê-la em igChart, conforme mostrado na lista abaixo:

    $("#columnChart").igDataChart({
        width: "98%",
        height: "350px",
        dataSource: "http://localhost:56649/api/Cities",
        legend: { element: "columnLegend" },
        title: "Cities Population",
        subtitle: "Population of Indian cities",
        axes: [{
            name: "xAxis",
            type: "categoryX",
            label: "Name",
            labelTopMargin: 5
        }, {
            name: "yAxis",
            type: "numericY",
            title: "in Millions",
        }],

        series: [{
            name: "series1",
            title: "2001",
            type: "column",
            isHighlightingEnabled: true,
            isTransitionInEnabled: true,
            xAxis: "xAxis",
            yAxis: "yAxis",
            valueMemberPath: "Population01"
        }, {
            name: "series2",
            title: "2005",
            type: "column",
            isHighlightingEnabled: true,
            isTransitionInEnabled: true,
            xAxis: "xAxis",
            yAxis: "yAxis",
            valueMemberPath: "Population05"
        }, {
            name: "series3",
            title: "2010",
            type: "column",
            isHighlightingEnabled: true,
            isTransitionInEnabled: true,
            xAxis: "xAxis",
            yAxis: "yAxis",
            valueMemberPath: "Population10"
        },
        {
            name: "series4",
            title: "2015",
            type: "column",
            isHighlightingEnabled: true,
            isTransitionInEnabled: true,
            xAxis: "xAxis",
            yAxis: "yAxis",
            valueMemberPath: "Population15"
        }]
    });

Aqui estamos definindo as seguintes propriedades para criar o gráfico:

  • A propriedade da fonte de dados é definida como API/Cities para buscar todas as informações de Cities na operação HTTP GET
  • A legenda do gráfico como legenda da coluna
  • A altura e a largura do gráfico
  • O título e o subtítulo do gráfico
  • Os XAxis e YAxis do gráfico
  • Também criamos a série definindo as seguintes propriedades:
    • Nome
    • Título
    • Tipo
    • valueMemberPath – Deve ser definido como o nome da coluna numérica da entidade City.

Ao executar o aplicativo, você descobrirá que os dados da cidade da API Web foram mostrados renderizados no gráfico, conforme mostrado na imagem abaixo:

Grade e gráfico do IgniteUI com ASP.NET Web API

Conclusão

Aí está! Nesta postagem, aprendemos como criar ASP.NET API Web usando o padrão Repository e a abordagem de código primeiro do Entity Framework. Espero que você ache este post útil e obrigado por ler!

Solicite uma demonstração