Trabalhar com dados
Dica
Esse conteúdo é um trecho do livro eletrônico, Blazor para Desenvolvedores do ASP NET Web Forms para o Azure, disponível no .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
O acesso a dados é o backbone de um aplicativo ASP.NET Web Forms. Quando você está criando formulários para a Web, o que acontece com esses dados? Com o Web Forms, havia várias técnicas de acesso a dados que você podia usar para interagir com um banco de dados:
- Fontes de dados
- ADO.NET
- Entity Framework
As fontes de dados eram controles que você podia colocar em uma página do Web Forms e configurar como outros controles. O Visual Studio forneceu um conjunto amigável de caixas de diálogo para configurar e associar os controles às páginas do Web Forms. Os desenvolvedores que gostam de uma abordagem de "código baixo" ou "sem código" preferiram essa técnica quando o Web Forms foi lançado pela primeira vez.
O ADO.NET é a abordagem de baixo nível para interagir com um banco de dados. Seus aplicativos podem criar uma conexão com o banco de dados com Comandos, Tabelas de Dados e Conjuntos de Dados para interagir. Em seguida, os resultados podem ser associados a campos na tela sem muito código. A desvantagem dessa abordagem é que cada conjunto de objetos do ADO.NET (Connection
, Command
e DataTable
) estava associado a bibliotecas oferecidas por um fornecedor de banco de dados. O uso desses componentes deixou o código rígido e difícil de ser migrado para um banco de dados diferente.
Entity Framework
O EF (Entity Framework) é a estrutura de mapeamento relacional de software livre mantido pelo .NET Foundation. Lançado inicialmente com o .NET Framework, o EF permite gerar código para conexões de banco de dados, esquemas de armazenamento e interações. Com essa abstração, você pode se concentrar nas regras de negócios do aplicativo e permitir que o banco de dados seja gerenciado por um administrador de banco de dados confiável. No .NET, você pode usar uma versão atualizada do EF chamada EF Core. O EF Core ajuda a gerar e manter as interações entre o código e o banco de dados com uma série de comandos disponíveis por meio da ferramenta de linha de comando dotnet ef
. Vamos dar uma olhada em alguns exemplos para que você possa trabalhar com um banco de dados.
Code First do EF
Uma forma rápida de começar a criar interações de banco de dados é começar com os objetos de classe com os quais você deseja trabalhar. O EF oferece uma ferramenta para ajudar a gerar o código de banco de dados apropriado para suas classes. Essa abordagem é chamada de desenvolvimento "Code First". Considere a classe Product
a seguir para um aplicativo de vitrine de exemplo que queremos armazenar em um banco de dados relacional, como o 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; }
}
O produto tem uma chave primária e três campos adicionais que seriam criados no banco de dados:
- O EF identificará a propriedade
Id
como uma chave primária por convenção. - A
Name
será armazenada em uma coluna configurada para armazenamento de texto. O atributo[Required]
que aprimora essa propriedade adicionará uma restriçãonot null
para ajudar a impor esse comportamento declarado da propriedade. - O
Description
será armazenado em uma coluna configurada para armazenamento de texto e terá um comprimento máximo configurado de 4000 caracteres determinado pelo atributo[MaxLength]
. O esquema de banco de dados será configurado com uma coluna chamadaMaxLength
usando o tipo de dadosvarchar(4000)
. - A propriedade
Price
será armazenada como moeda. O atributo[Range]
vai gerar restrições apropriadas para impedir o armazenamento de dados fora dos valores mínimos e máximos declarados.
Precisamos adicionar essa classe Product
a uma classe de contexto de banco de dados que defina as operações de conexão e conversão com nosso banco de dados.
public class MyDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
A classe MyDbContext
fornece a única propriedade que define o acesso e a conversão para a classe Product
. O aplicativo configura essa classe para interação com o banco de dados usando as seguintes entradas no método Startup
da classe ConfigureServices
(ou o local apropriado em Program.cs usando a propriedade builder.Services
em vez de services
):
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("MY DATABASE CONNECTION STRING"));
O código anterior se conectará a um banco de dados do SQL Server com a cadeia de conexão especificada. Você pode colocar a cadeia de conexão no arquivo appsettings.json, em variáveis de ambiente ou em outros locais de armazenamento de configuração e substituir corretamente essa cadeia de caracteres inserida.
Em seguida, você pode gerar a tabela de banco de dados apropriada para essa classe usando os seguintes comandos:
dotnet ef migrations add 'Create Product table'
dotnet ef database update
O primeiro comando define as alterações que você está fazendo no esquema de banco de dados como uma nova Migração do EF chamada Create Product table
. Uma Migração define como aplicar e remover as novas alterações de banco de dados.
Após a aplicação, haverá uma tabela Product
simples no banco de dados e algumas novas classes adicionadas ao projeto para ajudar a gerenciar o esquema de banco de dados. Encontre essas classes geradas, por padrão, em uma nova pasta chamada Migrações. Quando você faz alterações na classe Product
ou adiciona classes mais relacionadas para interação com o banco de dados, é necessário executar os comandos de linha de comando novamente com um novo nome da migração. Esse comando vai gerar outro conjunto de classes de migração para atualizar o esquema de banco de dados.
Database First do EF
Para bancos de dados existentes, você pode gerar as classes para o EF Core usando as ferramentas de linha de comando do .NET. Para fazer scaffold das classes, use uma variação do seguinte comando:
dotnet ef dbcontext scaffold "CONNECTION STRING" Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t Product -t Customer
O comando anterior se conecta ao banco de dados usando a cadeia de conexão especificada e o provedor Microsoft.EntityFrameworkCore.SqlServer
. Após a conexão, uma classe de contexto de banco de dados chamada MyDbContext
é criada. Além disso, as classes de suporte são criadas para as tabelas Product
e Customer
, que foram especificadas com as opções -t
. Há muitas opções de configuração para esse comando gerar a hierarquia de classe apropriada para o banco de dados. Para obter a referência completa, confira a Documentação do comando.
Mais informações sobre o EF Core podem ser encontradas no site Microsoft Docs.
Interagir com serviços Web
Quando o ASP.NET foi lançado pela primeira vez, os serviços SOAP eram a maneira preferencial para servidores Web e clientes trocarem dados. Muita coisa mudou desde então, e as interações preferenciais com os serviços passaram a ser interações diretas com o cliente HTTP. Com o ASP.NET Core e o Blazor, você pode registrar a configuração do HttpClient
em Program.cs ou no método Startup
da classe ConfigureServices
. Use essa configuração quando precisar interagir com o ponto de extremidade HTTP. Considere o seguinte código de configuração:
// 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");
});
Sempre que precisar acessar dados do GitHub, crie um cliente com o nome github
. O cliente é configurado com o endereço básico e os cabeçalhos de solicitação são definidos corretamente. Injete o IHttpClientFactory
nos componentes Blazor com a diretiva @inject
ou um atributo [Inject]
em uma propriedade. Crie o cliente nomeado e interaja com os serviços usando a seguinte sintaxe:
@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();
}
}
Esse método retorna a cadeia de caracteres que descreve a coleção de problemas no repositório dotnet/docs do GitHub. Ele retorna conteúdo no formato JSON e é desserializado em objetos de problema do GitHub apropriados. Há várias maneiras de configurar o HttpClientFactory
para entregar objetos pré-configurados HttpClient
. Tente configurar várias instâncias de HttpClient
com nomes e pontos de extremidade diferentes para os vários serviços Web com os quais você trabalha. Essa abordagem facilitará o trabalho das interações com esses serviços em cada página. Para obter mais informações, confira Fazer solicitações HTTP usando IHttpClientFactory.