Creación de ASP.NET API web con el enfoque de Code First y el patrón de repositorio de Entity Framework
En este artículo, aprenderemos a crear una API web ASP.NET utilizando el patrón de repositorio y el enfoque de código primero de Entity Framework.
En este artículo, aprenderemos a crear una API web ASP.NET utilizando el patrón de repositorio y el enfoque de código primero de Entity Framework.
Básicamente, aprenderá a:
- Cree un proyecto central que contendrá la entidad y la interfaz del repositorio;
- Cree un proyecto de infraestructura que contenga código de operaciones de base de datos mediante el enfoque de código primero de Entity Framework;
- Cree una API web para realizar operaciones CRUD en la entidad;
- Consuma la API web en una aplicación jQuery y represente los datos en el gráfico Ignite UI.
¿Qué es un patrón de repositorio?
Primero entendamos por qué necesitamos un patrón de repositorio. Si no sigue un patrón de repositorio y utiliza directamente los datos, pueden surgir los siguientes problemas:
- Duplicate code
- Dificultad para implementar cualquier lógica o política relacionada con los datos, de modo que el almacenamiento en caché
- Dificultad para realizar pruebas unitarias de la lógica de negocio sin tener la capa de acceso a los datos
- Lógica de negocios y lógica de acceso a bases de datos estrechamente acopladas
Al implementar un patrón de repositorio podemos evitar los problemas anteriores y obtener las siguientes ventajas:
- La lógica de negocios se puede probar unitariamente sin lógica de acceso a datos
- El código de acceso a la base de datos se puede reutilizar
- El código de acceso a la base de datos se administra de forma centralizada, por lo que es fácil implementar cualquier política de acceso a la base de datos, de modo que el almacenamiento en caché
- Lógicas de dominio fáciles de implementar
- Las entidades de dominio o las entidades de negocio se escriben de forma segura con las anotaciones.
Ahora que hemos enumerado lo geniales que son, sigamos adelante y comencemos a implantar un patrón de repositorio en la API web de ASP.NET.
Creación del proyecto principal
En el proyecto principal, debe mantener las entidades y las interfaces del repositorio. En este ejemplo vamos a trabajar con la entidad City. Así que vamos a crear una clase City como se muestra en el listado a continuación:
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 puede ver, estamos anotando datos mediante el atributo Required, que forma parte de System.ComponentModel.DataAnnotations. Podemos poner anotaciones en la entidad de la ciudad utilizando cualquiera de estos dos enfoques:
- Uso de System.ComponentModel.DataAnnotations
- Using the Entity Framework Fluent API
Ambos enfoques tienen sus propias ventajas. Si considera que la restricción de las entidades de dominio es parte del dominio, utilice anotaciones de datos en el proyecto principal. Sin embargo, si considera que las restricciones están relacionadas con la base de datos y usa Entity Framework como tecnología de base de datos, opte por una API fluida.
A continuación, sigamos adelante y creemos la interfaz del repositorio. Cualquier operación que desee realizar en la entidad City debe formar parte de la interfaz del repositorio. La interfaz ICityRepository se puede crear como se muestra en la lista a continuación:
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);
}
}
Tenga en cuenta que el proyecto principal nunca debe contener ningún código relacionado con las operaciones de la base de datos. Por lo tanto, las siguientes referencias no deben ser parte del proyecto principal:
- Referencia a cualquier biblioteca externa
- Referencia a cualquier biblioteca de bases de datos
- Referencia a cualquier ORM como LINQ to SQL, entity framework, etc.
Después de agregar la clase de entidad y la interfaz del repositorio, el proyecto principal debería tener un aspecto similar al de la imagen siguiente:

Creación del proyecto de infraestructura
En el proyecto de infraestructura, realizamos operaciones que están relacionadas con fuera de la aplicación. Por ejemplo:
- Database operations
- Consumo de servicios web
- Acceso a los sistemas de archivos
Para realizar la operación de la base de datos vamos a utilizar el enfoque de Entity Framework Code First. Tenga en cuenta que ya hemos creado la entidad de la ciudad en la que se deben realizar las operaciones CRUD. Básicamente, para habilitar las operaciones CRUD, se requieren las siguientes clases:
- DataContext class
- Clase de repositorio que implementa la interfaz de repositorio creada en el proyecto principal
- DataBaseInitalizer class
A continuación, debemos agregar las siguientes referencias en el proyecto de infraestructura:
- Una referencia del marco de Entity. Para agregar esto, haga clic con el botón derecho en el proyecto y haga clic en administrar el paquete Nuget y luego instale Entity Framework
- Una referencia del proyecto principal
DataContext class
In the DataContext class:
- Cree una propiedad DbSet que creará la tabla para la entidad City
- En el constructor de la clase DataContext, pase el nombre de la cadena de conexión donde se crearía la base de datos
- CityDataContext class will inherit the DbContext class
La clase CityDataContext se puede crear como se muestra en la lista a continuación:
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, puede pasar la cadena de conexión o confiar en Entity Framework para crear la base de datos. Configuraremos la cadena de conexión en app.config del proyecto de infraestructura. Sigamos adelante y configuremos la cadena de conexión como se muestra en la siguiente lista:
<connectionStrings> <add name="cityconnectionstring" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=CityPolulation;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/> </connectionStrings>
Clase de inicialización de base de datos
Necesitamos crear una clase de inicialización de base de datos para alimentar la base de datos con algún valor inicial en el momento de la creación. Para crear la clase de inicialización de base de datos, cree una clase y heredarla de DropCreateDatabaseIfModelChnages. Aquí estamos estableciendo el valor para que, si el modelo cambia, vuelva a crear la base de datos. También podemos explorar las otras opciones del marco de entidades y heredar la clase de inicialización de la base de datos de la clase de estanque cruzado. En el método Seed podemos establecer el valor inicial para la tabla Cities. Con un registro de tres ciudades, se puede crear la clase inicializadora de base de datos como se muestra en la lista a continuación:
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
Hasta ahora hemos creado las clases DataContext y DatabaseInitalize. Usaremos la clase DataContext en la clase repository. La clase CityRepository implementará la interfaz ICityRepository del proyecto principal y realizará operaciones CRUD mediante la clase DataContext. La clase CityRepository se puede implementar como se muestra en la lista a continuación:
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;
}
}
}
La implementación de la clase CityRepository es muy sencilla. Puede ver que estamos usando el código habitual de LINQ to Entity para realizar las operaciones CRUD. Después de implementar todas las clases, el proyecto de infraestructura debería tener un aspecto similar al de la siguiente imagen:

Create the WebAPI project
Ahora vamos a seguir adelante y crear el proyecto de API web. Para comenzar, debemos agregar las siguientes referencias:
- Referencia del proyecto principal
- Referencia del proyecto de infraestructura
- Referencia del marco de la entidad
Después de agregar todas las referencias en el proyecto de API web, copie la cadena de conexión (agregada en el paso anterior cityconnectionstring) de la aplicación. Configuración del proyecto de infraestructura en el archivo web.config del proyecto de API web. A continuación, abra el archivo Global.asax y en el método Application_Start(), agregue las siguientes líneas de código para asegurarse de que los datos iniciales se hayan insertado en la base de datos:
CityDbInitalize db = new CityDbInitalize(); System.Data.Entity.Database.SetInitializer(db);
En este punto, compile el proyecto de API web y, a continuación, haga clic con el botón derecho en la carpeta Controllers y en un nuevo controlador. Cree un nuevo controlador con el andamiaje, eligiendo Controlador de API web 2 con acciones, utilizando la opción Entity Framework como se muestra en la imagen siguiente:

A continuación, para agregar el Controlador, seleccione la clase City como clase Model y la clase CityDataContext como clase de contexto Data.

Una vez que haga clic en Agregar, encontrará que se ha creado un controlador de API web con el nombre CitiesController en la carpeta Controladores. En este punto, cuando siga adelante y ejecute la API web, debería poder OBTENER las ciudades en el navegador como se muestra en la imagen a continuación:

Aquí hemos creado la API web utilizando el enfoque CodeFirst de Entity Framework y el patrón Repository. Puede realizar operaciones CRUD mediante operaciones POST, GET, PUT y DELETE en la URL de api/cities.
JQuery Client to consume Web API
Ahora sigamos adelante y mostremos la población de las ciudades en un igChart. Agregué referencias de los archivos JS y CSS de IgniteUI en el HTML como se muestra en la siguiente lista:
<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>
En el elemento Body, agregué como tabla como se muestra en la lista a continuación:
<table>
<tr>
<td id="columnChart" class="chartElement"></td>
<td id="columnLegend" style="float: left"></td>
</tr>
</table>
Para convertir la tabla a igChart en la función de listo para documentos de jQuery, debemos seleccionar la tabla y convertirla a igChart como se muestra en la lista a continuación:
$("#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"
}]
});
Aquí estamos configurando las siguientes propiedades para crear el gráfico:
- La propiedad de origen de datos se establece en API/Cities para capturar toda la información de Cities en la operación HTTP GET
- La leyenda del gráfico como leyenda de columna
- La altura y la anchura del gráfico
- El título y el subtítulo del gráfico
- Los XAxis y YAxis del gráfico
- También creamos la serie estableciendo las siguientes propiedades:
- Nombre
- Título
- Tipo
- valueMemberPath: debe establecerse en el nombre de la columna numérica de la entidad City.
Al ejecutar la aplicación, encontrará que los datos de la ciudad de la API web se han mostrado representados en el gráfico como se muestra en la imagen a continuación:

Conclusión
¡Ahí lo tienes! En esta publicación, aprendimos cómo crear ASP.NET API web utilizando el patrón de repositorio y el enfoque de código primero de Entity Framework. Espero que este post os sea útil, ¡y gracias por leer!
