Uso dei dati

Suggerimento

Questo contenuto è un estratto dell'eBook, Blazor per gli sviluppatori di Web Forms ASP.NET per Azure, disponibile in .NET Docs o come PDF scaricabile gratuitamente che può essere letto offline.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover thumbnail.

L'accesso ai dati è la colonna portante di un'app Web Forms ASP.NET. Se si creano moduli per il Web, cosa succede ai dati? Con Web Form è possibile interagire con un database con diverse tecniche di accesso ai dati:

  • Origini dati
  • ADO.NET
  • Entity Framework

Le origini dati erano controlli che potevano essere inseriti in una pagina Web Form e configurati come altri controlli. Visual Studio forniva un semplice set di finestre di dialogo per configurare e associare i controlli alle pagine Web Form. Gli sviluppatori con un approccio "low code" o "no code" preferivano questa tecnica quando Web Form è stato rilasciato per la prima volta.

Data Sources

ADO.NET è l'approccio di basso livello per interagire con un database. Le app possono creare una connessione con il database tramite comandi, tabelle dati e set di dati per l'interazione. I risultati potrebbero quindi essere associati a campi dello schermo a bassa quantità di codice. Lo svantaggio di questo approccio era che ogni set di oggetti ADO.NET (Connection, Commande DataTable) era associato alle librerie fornite da un fornitore di database. L'uso di questi componenti rendeva il codice rigido e difficile da migrare a un altro database.

Entity Framework

Entity Framework (EF) è il framework di mapping relazionale di oggetti open source gestito da .NET Foundation. Inizialmente rilasciato con .NET Framework, EF consente di generare codice per le connessioni di database, schemi di archiviazione e interazioni. Con questa astrazione, è possibile concentrarsi sulle regole business dell'app e consentire la gestione del database da parte di un amministratore di database attendibile. In .NET, è possibile usare una versione aggiornata di ENTITY chiamata EF Core. EF Core consente di generare e gestire le interazioni tra codice e database con una serie di comandi disponibili per l'utente tramite lo strumento dotnet ef della riga di comando. Verranno ora esaminati alcuni esempi per imparare a lavorare con un database.

EF Code First

Un modo rapido per iniziare a creare interazioni con il database consiste nell'iniziare con gli oggetti classe con cui si vuole lavorare. EF fornisce uno strumento per generare il codice di database appropriato per le classi. Questo approccio è chiamato sviluppo "Code First". Considerare la seguente classe Product per un'app storefront di esempio che si desidera archiviare in un database relazionale come 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; }
}

Il prodotto ha una chiave primaria e tre campi aggiuntivi che verrebbero creati nel database:

  • Per convenzione, EF identificherà la proprietà Id come chiave primaria.
  • Name verrà archiviato in una colonna configurata per l'archiviazione di testo. L'attributo [Required] di questa proprietà aggiungerà un vincolo not null per imporre questo comportamento dichiarato della proprietà.
  • Description verrà archiviato in una colonna configurata per l'archiviazione di testo e avrà una lunghezza massima configurata di 4000 caratteri, come imposto dall'attributo [MaxLength]. Lo schema del database verrà configurato con una colonna denominata MaxLength usando il tipo di dati varchar(4000).
  • La proprietà Price verrà archiviata come valuta. L'attributo [Range] genererà vincoli appropriati per impedire l'archiviazione di dati al di fuori dei valori minimi e massimi dichiarati.

È necessario aggiungere la classe Product a una classe di contesto di database che definisce le operazioni di connessione e conversione con il database.

public class MyDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
}

La classe MyDbContext fornisce la proprietà che definisce accesso e traduzione per la classe Product. L'applicazione configura questa classe per l'interazione con il database usando le seguenti voci nel metodo Startup della classe ConfigureServices (o il percorso adeguato in Program.cs usando la builder.Services proprietà anziché services):

services.AddDbContext<MyDbContext>(options =>
    options.UseSqlServer("MY DATABASE CONNECTION STRING"));

Il codice precedente si connetterà a un database di SQL Server con la stringa di connessione indicata. È possibile inserire la stringa di connessione nel file appsettings.json, nelle variabili di ambiente o in altri percorsi di archiviazione della configurazione, e sostituire adeguatamente la stringa incorporata.

Quindi, è possibile generare la tabella di database adeguata per questa classe usando i seguenti comandi:

dotnet ef migrations add 'Create Product table'
dotnet ef database update

Il primo comando definisce le modifiche apportate allo schema del database come nuova migrazione di Entity Framework denominata Create Product table. Una migrazione definisce come applicare e rimuovere le modifiche al nuovo database.

Dopo l'applicazione, si otterrà una semplice tabella Product nel database e alcune nuove classi aggiunte al progetto che consentono di gestire lo schema del database. Per impostazione predefinita, queste classi generate si trovano in una nuova cartella denominata Migrazioni. Quando si apportano modifiche alla classe Product o si aggiungono altre classi correlate per farle interagire con il database, è necessario eseguire nuovamente i comandi della riga di comando con un nuovo nome della migrazione. Questo comando genererà un altro set di classi di migrazione per aggiornare lo schema del database.

Database First

Per database esistenti, è possibile generare le classi per EF Core usando gli strumenti della riga di comando .NET. Per eseguire lo scaffolding delle classi, usare una variante del seguente comando:

dotnet ef dbcontext scaffold "CONNECTION STRING" Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t Product -t Customer

Il comando precedente effettua la connessione al database usando la stringa di connessione e indicata e il provider Microsoft.EntityFrameworkCore.SqlServer. Dopo che la connessione è stata effettuata, viene creata una classe di contesto del database denominata MyDbContext. Vengono inoltre create classi di supporto per le tabelle Product e Customer specificate con le opzioni -t. Per questo comando sono disponibili molte opzioni di configurazione volte a generare la gerarchia di classi appropriata per il database. Per informazioni complete, consultare la documentazione del comando.

Ulteriori informazioni su EF Core sono disponibili sul sito Microsoft Docs.

Interagire con servizi Web

Quando ASP.NET è stato rilasciato per la prima volta, i servizi SOAP erano il mezzo preferito per lo scambio di dati tra server Web e client. Molte cose sono cambiate da allora, e le interazioni dirette dei client HTTP sono diventate la modalità preferita per interagire con servizi. Con ASP.NET Core e Blazor, è possibile registrare la configurazione di HttpClient in Program.cs o nel metodo Startup della classe ConfigureServices. Usare questa configurazione quando si deve interagire con l'endpoint HTTP. Considerare il seguente codice di configurazione:

// 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");
});

Quando si desidera accedere a dati da GitHub, creare un client denominato github. Il client viene configurato con l'indirizzo di base e le intestazioni della richiesta vengono impostate in modo adeguato. Inserire l'oggetto IHttpClientFactory nei componenti Blazor con la direttiva @inject o un attributo [Inject] in una proprietà. Creare il client che si è denominato e interagire con i servizi usando la seguente sintassi:

@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();
    }
}

Questo metodo restituisce la stringa che descrive la raccolta di problemi nel repository di GitHub dotnet/docs. Restituisce il contenuto in formato JSON e viene deserializzato in oggetti problema di GitHub adeguati. Esistono molti modi per configurare HttpClientFactory per recapitare oggetti preconfigurati HttpClient. Provare a configurare più istanze HttpClient con diversi nomi ed endpoint per i vari servizi Web usati. Questo approccio renderà le interazioni con questi servizi sempre più facili. Per ulteriori informazioni, consultare Effettuare richieste HTTP usando IHttpClientFactory.