Il mondo NoSql rappresenta al giorno d'oggi una matura tecnologia per la gestione dei dati, che si contrappone, con pro e contro, al modello relazionale. In questo ambito, MongoDB (https://www.mongodb.com/) rappresenta una delle soluzioni più popolari, oltre che gratuita e open source. Inoltre, un assoluto punto a favore è rappresentato dal fatto che il nuovo Azure Cosmos DB (https://docs.microsoft.com/en-us/azure/cosmos-db/introduction) è compatibile con le Mongo API, così che possiamo scrivere la nostra solution basandola su un database Mongo locale e portarla, senza troppi sforzi, sul cloud di Microsoft.

Primi passi

Un database documentale si differenzia dal modello relazionale perchè permette di memorizzare informazioni sotto forma di documenti, ossia dati non strutturati, solitamente file JSON, che vengono poi indicizzati per poter assicurare alte prestazioni in fase di ricerca. Questo fa sì che non dobbiamo più mappare entità complesse su una o più tabelle, relazionarle con foreign key ed eseguire complesse query per recuperare un dato. In un database documentale, un'entità complessa viene serializzata e deserializzata nella sua interezza, e memorizzata come tale.

Per iniziare a utilizzare MongoDB, dobbiamo innanzitutto installare il server. Una delle opzioni è scaricarlo dal sito ufficiale (https://www.mongodb.com/download-center#community); una valida alternativa, se abbiamo Docker installato sulla nostra macchina di sviluppo, è quella di eseguire il comando seguente dalla shell, per effettuare il download e mandare automaticamente in esecuzione il container.

docker run -p 27017:27017 -d mongo

In entrambi i casi, ci ritroveremo a disposizione un'istanza locale di MongoDB, esposta per default sulla porta 27017, che siamo pronti a utilizzare da ASP.NET Core.

Configurazione di ASP.NET Core

Se abbiamo creato una solution da zero, prima di poter interagire con MongoDB è indispensabile installare il relativo driver tramite NuGet. MongoDB.Driver è il package ufficiale che, come al solito, possiamo ricercare sulla GUI di Visual Studio o referenziare tramite il comando PowerShell seguente:

Install-Package MongoDB.Driver

Questo package espone un paio di oggetti di cui avremo bisogno a brevissimo, quando inizieremo a interagire con la base dati:

  • IMongoClient, che rappresenta un pool di connessioni a un server MongoDB;
  • IMongoDatabase, che invece ci consente di accedere a un database.

Come al solito, la best practice è quella di configurarli nel modulo di Startup, all'interno del metodo ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddSingleton<IMongoClient>(x => new MongoClient(Configuration.GetConnectionString("mongo")));
    services.AddTransient<IMongoDatabase>(x => x.GetService<IMongoClient>().GetDatabase("MyTestDb"));
}

Nell'esempio, IMongoClient è registrato come Singleton e inizializzato passando una connection string che si trova all'interno di appSettings.json:

"ConnectionStrings": {
  "mongo": "mongodb://localhost"
}

Come possiamo notare, per default il server locale di mongo accetta anche connessioni non autenticate. In ogni modo, le credenziali possono essere specificate nella URL di connessione, quindi il codice che abbiamo visto rimane comunque valido.

IMongoDatabase, invece, è un'istanza transient e viene creata tramite il metodo GetDatabase, a cui passsiamo il nome del database che vorremo utilizzare.

Usiamo MongoDB per persistere un oggetto


Per provare a utilizzare MongoDB, il modo più semplice è quello di creare una entity e provare a persisterla. Nel nostro caso, possiamo fare i primi esperimenti con il mai troppo abusato oggetto Person:

public class Person
{
    public ObjectId Id { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }
}

L'unico aspetto da segnalare è costituito dalla proprietà Id. MongoDB, come è lecito aspettarsi, necessita che ogni oggetto abbia un Id univoco. Il modo più semplice è quello di sfruttare un oggetto denominato ObjectId, che implementa tutte le logiche di generazione per far sì che non ci siano sovrapposizioni tra due entità. Grazie alle naming convention di default, una proprietà di nome Id verrà immediatamente identificata dal client come identificativo dell'oggetto Person.

Una volta creata la nostra classe, passiamo a gestirla all'interno del controller PeopleController, che accetta un oggetto di tipo IMongoDatabase nel costruttore.

private readonly IMongoDatabase _db;
private readonly IMongoCollection<Person> _people;

public PeopleController(IMongoDatabase db)
{
    _db = db;
    _people = _db.GetCollection<Person>("people");
}

Il metodo GetCollection ci permette di referenziare una collection di Person del database, il cui nome è "people". Possiamo pensare a una collection come all'analogo di una tabella di un database relazionale, con la differenza che, ovviamente, in questo caso i dati sono non strutturati e non devono avere per forza forma tabellare.

Una volta ottenuta questa reference, possiamo recuperare un elenco di Person tramite il metodo FindAsync:

public async Task<IActionResult> Index()
{
    var filter = new BsonDocument();
    var query = await _people.FindAsync(filter);

    return View(await query.ToListAsync());
}

Il parametro filter ci permette di specificare dei filtri di ricerca, ma ne esploreremo le peculiarità in un successivo script.

Per inserire una nuova Person sul database, invece, possiamo sfruttare il metodo InsertOneAsync:

public async Task<IActionResult> Create([Bind("Name,Email")] Person person)
{
    if (ModelState.IsValid)
    {
        person.Id = ObjectId.GenerateNewId();
        await _people.InsertOneAsync(person);

        return RedirectToAction(nameof(Index));
    }

    return View(person);
}

Come possiamo notare, prima di inserire l'oggetto, dobbiamo generare un nuovo identificativo tramite il metodo ObjectId.GenerateNewId.

Conclusione

In questo script abbiamo mosso i primi passi per installare, referenziare e utilizzare MongoDB in un'applicazione ASP.NET Core. Nei prossimi script ci spingeremo un po' più nel dettaglio, per esempio per capire come recuperare oggetti, modificarli ed effettuare delle ricerche.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi