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.
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.
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
, Command
e 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 vincolonot 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 denominataMaxLength
usando il tipo di dativarchar(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.