Trabajar con datos
Sugerencia
Este contenido es un extracto del libro electrónico "Blazor for ASP.NET Web Forms Developers for Azure" (Blazor para desarrolladores de ASP.NET Web Forms), disponible en Documentación de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.
El acceso a datos es la base de una aplicación de ASP.NET Web Forms. Si va a crear formularios para la web, ¿qué ocurre con los datos? Con Web Forms, se podían usar varias técnicas de acceso a datos para interactuar con una base de datos:
- Orígenes de datos
- ADO.NET
- Entity Framework
Los orígenes de datos eran controles que se podían colocar en una página de Web Forms y se configuraban como otros controles. En Visual Studio se proporcionaba un conjunto descriptivo de cuadros de diálogo para configurar y enlazar los controles a las páginas de Web Forms. Los desarrolladores que disfrutan de un enfoque de "poco código" o "sin código" preferían esta técnica cuando se publicó Web Forms por primera vez.
ADO.NET es el enfoque de bajo nivel para interactuar con una base de datos. Las aplicaciones podían crear una conexión a la base de datos con comandos, tablas de datos y conjuntos de datos para interactuar. Después, los resultados se podían enlazar a campos en pantalla sin mucho código. El inconveniente de este enfoque era que cada conjunto de objetos ADO.NET (Connection
, Command
y DataTable
) estaba enlazado a bibliotecas proporcionadas por un proveedor de bases de datos. El uso de estos componentes hacía que el código fuera rígido y difícil de migrar a otra base de datos.
Entity Framework
Entity Framework (EF) es el marco de asignación relacional de objetos de código abierto mantenido por .NET Foundation. Publicado inicialmente con .NET Framework, EF permite generar código para las conexiones de base de datos, los esquemas de almacenamiento y las interacciones. Con esta abstracción, se puede centrar en las reglas de negocio de la aplicación y permitir que un administrador de bases de datos de confianza administre la base de datos. En .NET, puede usar una versión actualizada de EF denominada EF Core. EF Core facilita la generación y el mantenimiento de las interacciones entre el código y la base de datos con una serie de comandos disponibles mediante la herramienta de línea de comandos dotnet ef
. Ahora se examinarán algunos ejemplos para empezar a trabajar con una base de datos.
Code First de EF
Una forma rápida de empezar a crear las interacciones de base de datos consiste en comenzar con los objetos de clase con los que quiere trabajar. EF proporciona una herramienta que le ayudará a generar el código de base de datos adecuado para las clases. Este enfoque se denomina desarrollo "Code First". Considere la clase Product
siguiente para una aplicación de escaparate de ejemplo que se quiere almacenar en una base de datos relacional como Microsoft SQL Server.
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[MaxLength(4000)]
public string Description { get; set; }
[Range(0, 99999,99)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
El producto tiene una clave principal y tres campos adicionales que se crearían en la base de datos:
- Por convención, EF identificará la propiedad
Id
como clave principal. Name
se almacenará en una columna configurada para el almacenamiento de texto. El atributo[Required]
que decora esta propiedad agregará una restricciónnot null
para ayudar a aplicar este comportamiento declarado de la propiedad.Description
se almacenará en una columna configurada para el almacenamiento de texto y tendrá una longitud máxima configurada de 4000 caracteres como indica el atributo[MaxLength]
. El esquema de la base de datos se configurará con una columna denominadaMaxLength
con el tipo de datosvarchar(4000)
.- La propiedad
Price
se almacenará como moneda. El atributo[Range]
generará las restricciones adecuadas para evitar el almacenamiento de datos fuera de los valores mínimo y máximo declarados.
Es necesario agregar esta clase Product
a una clase de contexto de base de datos que defina las operaciones de conexión y traducción con la base de datos.
public class MyDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
La clase MyDbContext
proporciona una propiedad que define el acceso y la traducción de la clase Product
. La aplicación configura esta clase para la interacción con la base de datos mediante las siguientes entradas en el método ConfigureServices
de la clase Startup
, o bien la ubicación apropiada en Program.cs mediante la propiedad builder.Services
en lugar de services
:
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("MY DATABASE CONNECTION STRING"));
El código anterior se conectará a una base de datos de SQL Server con la cadena de conexión especificada. Puede colocar la cadena de conexión en el archivo appsettings.json, en variables de entorno o en otras ubicaciones de almacenamiento de configuración y reemplazar esta cadena insertada de la forma adecuada.
Después, puede generar la tabla de base de datos adecuada para esta clase mediante los comandos siguientes:
dotnet ef migrations add 'Create Product table'
dotnet ef database update
El primer comando define los cambios que se realizan en el esquema de base de datos como una nueva migración de EF denominada Create Product table
. Una migración define cómo aplicar y quitar los nuevos cambios de la base de datos.
Una vez que se ha aplicado, tiene una tabla Product
sencilla en la base de datos y varias clases nuevas agregadas al proyecto que facilitan la administración del esquema de la base de datos. Puede encontrar estas clases generadas, de forma predeterminada, en una nueva carpeta denominada Migrations. Cuando realice cambios en la clase Product
o agregue más clases relacionadas que quiera que interactúen con la base de datos, tendrá que volver a ejecutar los comandos de la línea de comandos con un nuevo nombre de la migración. Este comando generará otro conjunto de clases de migración para actualizar el esquema de la base de datos.
Database First de EF
Para las bases de datos existentes, puede generar las clases para EF Core con las herramientas de línea de comandos de .NET. Para aplicar scaffolding a las clases, use una variación del comando siguiente:
dotnet ef dbcontext scaffold "CONNECTION STRING" Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t Product -t Customer
El comando anterior se conecta a la base de datos mediante la cadena de conexión especificada y el proveedor Microsoft.EntityFrameworkCore.SqlServer
. Una vez que se ha realizado la conexión, se crea una clase de contexto de base de datos denominada MyDbContext
. Además, se crean clases auxiliares para las tablas Product
y Customer
que se han especificado con las opciones -t
. Hay muchas opciones de configuración para este comando con el fin de generar la jerarquía de clases adecuada para la base de datos. Para obtener una referencia completa, vea la documentación del comando.
Puede encontrar más información sobre EF Core en el sitio de Microsoft Docs.
Interacción con servicios web
Cuando se publicó ASP.NET por primera vez, los servicios SOAP eran el método preferido para el intercambio de datos entre clientes y servidores web. Desde entonces las cosas han cambiado mucho y las preferencias de interacción con los servicios se han orientado a interacciones directas con el cliente HTTP. Con ASP.NET Core y Blazor, puede registrar la configuración de HttpClient
en Program.cs o en el método ConfigureServices
de la clase Startup
. Use esa configuración cuando necesite interactuar con el punto de conexión HTTP. Considere el código de configuración siguiente:
// in Program.cs
builder.Services.AddHttpClient("github", client =>
{
client.BaseAddress = new Uri("http://api.github.com/");
// Github API versioning
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent", "BlazorWebForms-Sample");
});
Siempre que necesite acceder a datos desde GitHub, cree un cliente con el nombre github
. El cliente está configurado con la dirección base y los encabezados de solicitud se establecen de la forma correcta. Inserte IHttpClientFactory
en los componentes de Blazor con la directiva @inject
o un atributo [Inject]
en una propiedad. Cree el cliente con nombre e interactúe con los servicios mediante la sintaxis siguiente:
@inject IHttpClientFactory factory
...
@code {
protected override async Task OnInitializedAsync()
{
var client = factory.CreateClient("github");
var response = await client.GetAsync("repos/dotnet/docs/issues");
response.EnsureStatusCode();
var content = await response.Content.ReadAsStringAsync();
}
}
Este método devuelve la cadena que describe la colección de incidencias en el repositorio dotnet/docs de GitHub. Devuelve contenido en formato JSON y se deserializa en los objetos de incidencia de GitHub correspondientes. Hay muchas maneras de configurar HttpClientFactory
para proporcionar objetos HttpClient
preconfigurados. Intente configurar varias instancias de HttpClient
con distintos nombres y puntos de conexión para los diversos servicios web con los que trabaja. Este enfoque hará que sea más fácil trabajar con las interacciones con esos servicios en cada página. Para obtener más información, vea Realización de solicitudes HTTP con IHttpClientFactory.