Tutorial .Net MongoDB CRUD : C# le operazioni CRUD sul database MongoDB - seconda parte

Articolo conclusivo riguardante le operazioni di inserimento, aggiornamento e cancellazione dei documenti del database MongoDB Community.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

In questa seconda ed ultima parte, vedremo come gestire i documenti, in particolare l’inserimento, modifica e cancellazione dei dati, tramite la tecnologia .Net ed il linguaggio di programmazione C# .
Nel precedente articolo si è visto come collegarsi al database MongoDB e leggere i dati, in questa parte vedremo le restanti operazioni, come inserimento, cancellazione e modifica dei documenti.
Riprendendo il progetto precedente, scriveremo i codici per i vari pulsanti, che permettono appunto una gestione dei dati.

Stesura del codice

Facciamo doppio click sul pulsante “Inserisci”, in modo da passare in visualizzazione codice nell’evento click del pulsante. 
Tramite il metodo “InsertOne”, dell’oggetto di tipo “IMongoCollection” inseriamo il nuovo dato nella collection.
Di seguito si riporta il frammento di codice dell’evento click del pulsante “Inserisci”, con il quale si crea un’istanza del database ed un’istanza della collection, e tramite un oggetto di tipo BSonDocument

C#
private void BtnInserisci_Click(object sender, EventArgs e)
{
    try
    {
        if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
        {
            MessageBox.Show("Valorizzare le caselle Nome e Cognome");
            return;
        }
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        var database = clientMongoDB.GetDatabase("Amministrazione");
        var collection = database.GetCollection<BsonDocument>("Dati");
        // Creo un nuovo oggetto BsonDocument
        var nuovoDato = new BsonDocument
        {
            { "nome", TxtNome.Text },
            { "cognome", TxtCognome.Text },
            { "email", TxtNome.Text + TxtCognome.Text + "@dominio.it" }
        };
        // Inserisce il nuovo oggetto nella collection
        collection.InsertOne(nuovoDato);
        TxtCognome.Text = "";
        TxtNome.Text = "";
        // Ricarica i dati nella DataGridView
        CaricaDati2();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}
 

Possiamo inserire il dato anche tramite una nostra classe, utilizzeremo la classe creata nel precedente articolo per il rilevamento dei dati.
Tramite la classe “Dati”,   viene passata come riferimento per ottenere la collection, e tramite una nuova entità con i dati, viene passata al metodo “InsertOne”.
Si riporta di seguito la classe “Dati”, per gestire i dati.

C#
public class Dati
{
   public ObjectId _id { get; set; }
   public string nome { get; set; }
   public string cognome { get; set; }
   public string email { get; set; }
   public DateTime data_nascita { get; set; }
}


Di seguito si riporta il codice dell’evento click utilizzandolo come oggetto per l’inserimento dei dati.

C#
private void BtnInserisci_Click(object sender, EventArgs e)
{
   try
   {
       if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
       {
           MessageBox.Show("Valorizzare le caselle Nome e Cognome");
           return;
       }
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       var database = clientMongoDB.GetDatabase("Amministrazione");
       var collection = database.GetCollection<Dati>("Dati");
       // Crea un nuovo oggetto Dati
       var nuovoDato = new Dati
       {
           nome = TxtNome.Text,
           cognome = TxtCognome.Text,
           email = TxtNome.Text + TxtCognome.Text + "@dominio.it"
       };
       // Inserisce il nuovo oggetto nella collection
       collection.InsertOne(nuovoDato);
       TxtCognome.Text = "";
       TxtNome.Text = "";
       // Ricarica i dati nella DataGridView
       CaricaDati2();
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }

Tramite il metodo InsertMany, possiamo inserire più dati, ossia più record, passando un array (o lista) di oggetti al metodo.
Di seguito si riporta il frammento di codice di esempio per il metodo “InsertMany” che inserisci diversi documenti.

C#
private void BtnInserisci_Click(object sender, EventArgs e)
{
   try
   {
       if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
       {
           MessageBox.Show("Valorizzare le caselle Nome e Cognome");
           return;
       }
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       var database = clientMongoDB.GetDatabase("Amministrazione");
       var collection = database.GetCollection<Dati>("Dati");
       List<Dati> listaDati = new();
       for (int i = 0; i < 3; i++)
       {
           listaDati.Add(new Dati
           {
               nome = TxtNome.Text + i.ToString(),
               cognome = TxtCognome.Text + i.ToString(),
               email = TxtNome.Text + TxtCognome.Text + i.ToString() + "@dominio.it"
           });
       }
       // Inserisce una serie di oggetti nella collection
       collection.InsertMany(listaDati);
       TxtCognome.Text = "";
       TxtNome.Text = "";
       // Ricarica i dati nella DataGridView
       CaricaDati2();
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Modifica dei dati

In questa parte vediamo come modificare i dati, in particolare una volta rilevato un dato, lo modifichiamo e salviamo nella collection.
La modifica dei dati può avvenire in varie modalità, che vedremo qui di seguito.
Tramite la proprietà “Update”, possiamo effettuare la modifica con il metodo Set.
Utilizzando le classi “MongoClient, e I“MongoCollection”, possiamo gestire i dati, tramite il metodo ”eq”, della proprietà filter che effettua una ricerca, estrapoliamo il record che vogliamo modificare e tramite il metodo “UpdateOne”, modifichiamo il dato di nostro interesse.  Il metodo UpdateOne, ci restituisce un oggetto di tipo “updateResult” con il quale possiamo verificare se la modifica è andata a buon fine o no, tramite la proprietà “ModifiedCount” maggiore di 0.
Di seguito si riporta il frammento di codice delle suddette operazioni per la modifica di un record.

C#
private void BtnModifica_Click(object sender, EventArgs e)
{
    try
    {
        if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
        {
            MessageBox.Show("Valorizzare le caselle Nome e Cognome");
            return;
        }
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        var database = clientMongoDB.GetDatabase("Amministrazione");
        var collection = database.GetCollection<BsonDocument>("Dati");
        // Recupera il record selezionato dalla DataGridView                
        if (DgvDati.SelectedRows.Count == 0)
        {
            MessageBox.Show("Selezionare un record da modificare");
            return;
        }
        var selectedRow = DgvDati.SelectedRows[0];
        var id = selectedRow.Cells["ID"].Value.ToString();
        if (string.IsNullOrEmpty(id))
        {
            MessageBox.Show("ID non valido");
            return;
        }
        var objectId = new ObjectId(id);
        //Effettua un filtro per trovare il documento da modificare
        var filter = Builders<BsonDocument>.Filter.Eq( "_id", objectId);
  //Imposta i valori dei campi da modificare
        var recordDaAggiornare = Builders<BsonDocument>.Update.Set("nome", TxtNome.Text)
                                                      .Set("cognome", TxtCognome.Text)
                                                      .Set("email", TxtNome.Text + TxtCognome.Text + "@dominio.it");
        // Esegui l'aggiornamento
        var updateResult = collection.UpdateOne(filter, recordDaAggiornare);
        if (updateResult.ModifiedCount == 0)
        {
            MessageBox.Show("Nessun documento modificato. Verifica l'ID selezionato.");
            return;
        }
         TxtCognome.Text = "";
        TxtNome.Text = "";
        // Ricarica i dati nella DataGridView
        CaricaDati2();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return;
}

Nel caso che vogliamo modificare il dato con una classe, quindi tipizzato, sempre utilizzando la classe “Dati”, vista nei precedenti esempi di codice, possiamo fare nel seguente modo.

C#
private void BtnModifica_Click(object sender, EventArgs e)
{
    try
    {
        if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
        {
            MessageBox.Show("Valorizzare le caselle Nome e Cognome");
            return;
        }
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        var database = clientMongoDB.GetDatabase("Amministrazione");
        var collection = database.GetCollection<Dati>("Dati");
        // Recupera l'ID selezionato dalla DataGridView                
        if (DgvDati.SelectedRows.Count == 0)
        {
            MessageBox.Show("Selezionare un record da modificare");
            return;
        }   
        var selectedRow = DgvDati.SelectedRows[0];
        var id = selectedRow.Cells["ID"].Value.ToString();
        if (string.IsNullOrEmpty(id))
        {
            MessageBox.Show("ID non valido");
            return;
        }
        var objectId = new ObjectId(id);
        //Effettua un filtro per trovare il documento da modificare
        var filter = Builders<Dati>.Filter.Eq(d => d._id, objectId);
        var recordDaAggiornare = Builders<Dati>.Update.Set(d => d.nome, TxtNome.Text)
                                                      .Set(d => d.cognome, TxtCognome.Text)
                                                      .Set(d => d.email, TxtNome.Text + TxtCognome.Text + "@dominio.it");
        // Esegue l'aggiornamento
        var updateResult = collection.UpdateOne(filter, recordDaAggiornare);
        if (updateResult.ModifiedCount == 0)
        {
            MessageBox.Show("Nessun documento modificato. Verifica l'ID selezionato.");
            return;
        }
         TxtCognome.Text = "";
        TxtNome.Text = "";
        // Ricarica i dati nella DataGridView
        CaricaDati2();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Altra tecnica che permette di aggiornare il dato è quello di utilizzare il metodo “ReplaceOne”. Di seguito un esempio di tale utilizzo.

C#
private void BtnModifica_Click(object sender, EventArgs e)
{

    try
    {
        if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
        {
            MessageBox.Show("Valorizzare le caselle Nome e Cognome");
            return;
        }
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        var database = clientMongoDB.GetDatabase("Amministrazione");
        var collection = database.GetCollection<Dati>("Dati");
        // Recupera l'ID selezionato dalla DataGridView                
        if (DgvDati.SelectedRows.Count == 0)
        {
            MessageBox.Show("Selezionare una riga da modificare");
            return;
        }   
        var selectedRow = DgvDati.SelectedRows[0];
        var id = selectedRow.Cells["ID"].Value.ToString();
        if (string.IsNullOrEmpty(id))
        {
            MessageBox.Show("ID non valido");
            return;
        }
        var objectId = new ObjectId(id);
        // Crea un filtro per trovare il documento da modificare
        var filter = Builders<Dati>.Filter.Eq(d => d._id, objectId);
        // Crea un oggetto Dati con i nuovi valori
        var updatedDato = new Dati
        {
            _id = objectId, // Mantiene l'ID originale
            nome = TxtNome.Text,
            cognome = TxtCognome.Text,
            email = TxtNome.Text + TxtCognome.Text + "@dominio.it"
        };
        //Esegue l'aggiornamento
        var updateResult = collection.ReplaceOne(filter, updatedDato);
        if (updateResult.ModifiedCount == 0)
        {
            MessageBox.Show("Nessun documento modificato. Verifica l'ID selezionato.");
            return;
        }
        TxtCognome.Text = "";
        TxtNome.Text = "";
        // Ricarica i dati nella DataGridView
        CaricaDati2();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Nel caso che invece abbiamo l’esigenza di modificare più record possiamo utilizzare il metodo "UpdateMany". Di seguito si riporta il frammento di codice di tale utilizzo.

C#
private void BtnModifica2_Click(object sender, EventArgs e)
{
   try
   {
       if (TxtNome.Text.Trim() == "" || TxtCognome.Text.Trim() == "")
       {
           MessageBox.Show("Valorizzare le caselle Nome e Cognome");
           return;
       }
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       var database = clientMongoDB.GetDatabase("Amministrazione");
       var collection = database.GetCollection<Dati>("Dati");
       // Recupera il record selezionato dalla DataGridView
       if (DgvDati.SelectedRows.Count == 0)
       {
           MessageBox.Show("Selezionare una riga da modificare");
           return;
       }
       var selectedRow = DgvDati.SelectedRows[0];
       var nomeSelezionato = selectedRow.Cells["nome"].Value.ToString();
       if (string.IsNullOrEmpty(nomeSelezionato))
       {
           MessageBox.Show("record non trovato");
           return;
       }
       string nome = nomeSelezionato;
       //Effettua un filtro per trovare i  documenti da modificare
       var filter = Builders<Dati>.Filter.Eq (d => d.nome, nome);
       // Crea un oggetto Dati con i nuovi valori
       var updateDato = Builders<Dati>.Update.Set(d => d.cognome, TxtCognome.Text)
                                              .Set(d => d.email, "prova@dominio.it");
       // Esegue l'aggiornamento di tutti i record che soddisfano il filtro
        var updateResult = collection.UpdateMany(filter, updateDato);
       if (updateResult.ModifiedCount == 0)
           {
           MessageBox.Show("Nessun documento modificato. Verifica l'ID selezionato.");
           return;
       }
       TxtCognome.Text = "";
       TxtNome.Text = "";
       // Ricarica i dati nella DataGridView
       CaricaDati2();
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Cancellazione dei dati

Siamo giunti all’ultima parte della gestione dei dati nel database MongoDB, dopo le operazioni di lettura, inserimento e modifica dei dati, vedremo in questi esempi di codice la cancellazione.
La cancellazione dei dati avviene tramite il metodo “DeleteOne” della classe IMongoCollection, il quale funziona come visto nelle precedenti operazioni. 
In particolare dopo aver rilevato il documento da cancellare, viene passato al metodo,
Facciamo doppio click sul pulsante “BtnElimina”, in modo che passiamo in visualizzazione codice nell’evento click del pulsante “Elimina”.
Nell’evento click utilizzeremo le stesse classi e tecnica viste nell’operazione di modifica, in particolare dopo aver creato un oggetto “MongoClient” ed un oggetto  “IMongoCollection”, effettuiamo una ricerca nella collection per rilevare il dato da cancellare, che verrà passato al metodo “DeleteOne”.
Di seguito si riporta il codice delle suddette operazioni dell’evento click del pulsante.

C#
 private void BtnElimina_Click(object sender, EventArgs e)
 {
     try
     {
         if (DgvDati.SelectedRows.Count == 0)
         {
             MessageBox.Show("Selezionare una riga da eliminare");
             return;
         }
         var selectedRow = DgvDati.SelectedRows[0];
         var id = selectedRow.Cells["ID"].Value.ToString();
         if (string.IsNullOrEmpty(id))
         {
             MessageBox.Show("ID non valido");
             return;
         }
         var objectId = new ObjectId(id);
         var clientMongoDB = new MongoClient("mongodb://localhost:27017");
         var database = clientMongoDB.GetDatabase("Amministrazione");
         var collection = database.GetCollection<BsonDocument>("Dati");
         // Crea un filtro per trovare il documento da eliminare
         var filter = Builders<BsonDocument>.Filter.Eq("_id", objectId);
         // Esegue l'eliminazione del documento
         var deleteResult = collection.DeleteOne(filter);
         if (deleteResult.DeletedCount == 0)
         {
             MessageBox.Show("Nessun documento eliminato. Verifica l'ID selezionato.");
             return;
         }
         // Ricarica i dati nella DataGridView
         CaricaDati2();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }

Anche in questo caso, possiamo utilizzare una classe. Di seguito si riporta il frammento di codice per la cancellazione del dato, utilizzando la classe denominata “Dati” creata in precedenza.

C#
private void BtnElimina_Click(object sender, EventArgs e)
{
   try
   {
       if (DgvDati.SelectedRows.Count == 0)
       {
           MessageBox.Show("Selezionare una riga da eliminare");
           return;
       }
       var selectedRow = DgvDati.SelectedRows[0];
       var id = selectedRow.Cells["ID"].Value.ToString();
       if (string.IsNullOrEmpty(id))
       {
           MessageBox.Show("ID non valido");
           return;
       }
       var objectId = new ObjectId(id);
       var clientMongoDB = new MongoClient("mongodb://localhost:27017");
       var database = clientMongoDB.GetDatabase("Amministrazione");
       var collection = database.GetCollection<Dati>("Dati");
       // Crea un filtro per trovare il documento da eliminare
       var filter = Builders<Dati>.Filter.Eq("_id", objectId);
       // Esegue l'eliminazione del documento
       var deleteResult = collection.DeleteOne(filter);
       if (deleteResult.DeletedCount == 0)
       {
           MessageBox.Show("Nessun documento eliminato. Verifica l'ID selezionato.");
           return;
       }
       // Ricarica i dati nella DataGridView
       CaricaDati2();
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
}

Nel caso che invece vogliamo cancellare più dati, dobbiamo utilizzare il metodo “DeleteMany”.Di seguito si riporta un esempio di codice.

C#
 private void BtnEliminaDipiù_Click(object sender, EventArgs e)
 {
     try
     {
         if (DgvDati.SelectedRows.Count == 0)
         {
             MessageBox.Show("Selezionare una riga da eliminare");
             return;
         }
         var selectedRow = DgvDati.SelectedRows[0];
         var nomeSelezionato = selectedRow.Cells["nome"].Value.ToString();
         if (string.IsNullOrEmpty(nomeSelezionato))
         {
             MessageBox.Show("record non trovato");
             return;
         }
         string nome = nomeSelezionato;
         var clientMongoDB = new MongoClient("mongodb://localhost:27017");
         var database = clientMongoDB.GetDatabase("Amministrazione");
         var collection = database.GetCollection<BsonDocument>("Dati");
         // Crea un filtro per trovare i  documenti da eliminare
         var filter = Builders<BsonDocument>.Filter.Eq("nome", nome);
         // Esegue l'eliminazione del documento
         var deleteResult = collection.DeleteMany(filter);
         if (deleteResult.DeletedCount == 0)
         {
             MessageBox.Show("Nessun documento eliminato. Verificare il nome selezionato.");
             return;
         }
         // Ricarica i dati nella DataGridView
         CaricaDati2();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }

Possiamo utilizzare anche in questo caso una classe per la cancellazione di più documenti, come si è visto per il singolo dato nel frammento di codice precedente, utilizzeremo le medesime classi,
Di seguito si riporta il frammento di codice per la cancellazione di più documenti, utilizzando una classe.

C#
private void BtnEliminaDipiù_Click(object sender, EventArgs e)
{
    try
    {
       if (DgvDati.SelectedRows.Count == 0)
        {
            MessageBox.Show("Selezionare una riga da eliminare");
            return;
        }
        var selectedRow = DgvDati.SelectedRows[0];
        var nomeSelezionato = selectedRow.Cells["nome"].Value.ToString();
        if (string.IsNullOrEmpty(nomeSelezionato))
        {
            MessageBox.Show("record non trovato");
            return;
        }
        string nome = nomeSelezionato;
        var clientMongoDB = new MongoClient("mongodb://localhost:27017");
        var database = clientMongoDB.GetDatabase("Amministrazione");
        var collection = database.GetCollection<Dati>("Dati");
       // Crea un filtro per trovare i  documenti da eliminare
        var filter = Builders<Dati>.Filter.Eq(d => d.nome, nome);
        // Esegue l'eliminazione del documento
        var deleteResult = collection.DeleteMany(filter);
        if (deleteResult.DeletedCount == 0)
        {
            MessageBox.Show("Nessun documento eliminato. Verificare il nome selezionato.");
            return;
        }
        // Ricarica i dati nella DataGridView
        CaricaDati2();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Conclusioni

L’articolo ha voluto fornire al lettore alcuni aspetti delle operazioni più comuni sui dati del database MongoDB Community. La gestione del database NoSql più utilizzando al mondo, quale appunto MongoDB, offre al programmatore semplicità e rapidità nello scrivere codice .Net per la gestione dei dati.  Aspetti importanti per realizzare applicazioni con tempi rapidi e facilmente scalabili.
L’articolo ha affrontato i vari scenari della gestione di una collection, affrontando in maniera introduttiva ed esauriente le varie operazioni sui documenti, quali, selezione, inserimento, modifica e cancellazione dei dati. 
Ricordiamo che il database utilizzato è MondoDB Community, una versione gratuita da installare sul proprio pc o server.