Winner's Excogitations

A chronicle of the thoughts, learning experiences, ideas and actions of a tech junkie, .NET, JS and Mobile dev, aspiring entrepreneur, devout Christian and travel enthusiast.

[HOW TO] Perform CRUD Operations with C# and MongoDB using LINQ
7 years ago ยท 4 minutes read

avqz8oxr4ybkuu76ph6t tvk3juatpld9khgnumc0

Introduction

As a quick refresher, MongoDB is an open-source document database and leading NoSQL database. MongoDB uses JSON-like documents with schemata. MongoDB is developed by MongoDB Inc. and licensed under the Server Side Public License (SSPL).

This guide is meant for everyone, but especially for those who have worked with Entity Framework and are trying their hands at MongoDB. The aim of this guide is to maintain a semblance of familiarity. This means we would not work with Find, FilterDefinition, Cursors and Bson instead, relying on the LINQ methods we have come to know and love. If the keywords mentioned do not mean anything to you, then this guide is for you. If they did, still peruse this article, it may offer some new ideas.

For the purpose of this guide, we would work with a simple POCO (Plain Old Csharp Object). This would define the typed object that we would create, read, update and delete.

using System;
using System.Collections.Generic;
using MongoDB.Bson.Serialization.Attributes;

class Appointment
{
  [BsonId]
  public int Id {get; set;}
  public DateTime StartDateTime {get; set;}
  public List<string> Attendees {get; set;}
}

Adding Data

Adding data to a collection is quite simple. You retrieve the collection, create an instance of your data model and insert. The code sample shows just that.

using MongoDB.Driver;
using System;
using System.Collections.Generic;

...

// set up mongo db
var connectionString = "mongodb://..."; // a mongo database url
var mongoClient = new MongoClient(connectionString);
var mongoDatabase = mongoClient.GetDatabase("database-name");
var collection = mongoDatabase.GetCollection<Appointment>("appointments");

...

// instantiate the object with the necessary data
var appointment = new Appointment
{
  Id = 12, // ensure no object has this value
  StartDateTime = DateTime.UtcNow.AddDays(2),
  Attendees = new List<string> { "Jane", "John" }
};

...

// persist the new object to the database
collection.InsertOne(appointment); // or await collection.InsertOneAsync(appointment); if you're all about that async life

It is as simple as that (mostly).

Retrieving Data

To retrieve data, the MongoDB client package provides the IMongoQueryable interface which allows us to run a number of operations on our data collections. A thing to note is that not all operations available on the IQueryable interface are currently translatable. Most of the staples are translatable though, this includes Skip, Take, First, FirstOrDefault, Count and Where amongst others.

NB: To make LINQ queries, you need to add using System.Linq; and using MongoDB.Driver.Linq; directives otherwise you may have compiler errors.

That said, let's say I want to find all appointments that would be holding two days from now and have a certain John attending, I want the first two results skipped and I want to limit my response to the first seven entries, my code should take the form:

using System;
using System.Linq;
using MongoDB.Driver.Linq;

...

// follow the mongo set up above

...

// retrieve the results to my strangely specific query
var matchedAppointments = collection
    .AsQueryable() // gets us that sweet sweet IMongoQueryable
    .Where(x => x.StartDateTime == DateTime.Now.Date.AddDays(3) && x.Attendees.Any(y => y == "John"))
    .Skip(2)
    .Take(7)
    .ToList();

Updating Data

Assuming I set the wrong value on an entry in the database collection or I just want to change a property on an entry. I need to follow a three-step process: retrieve the errant entry, update the fields, replace the old entry. The following code sample shows that in action:

using System;
using System.Linq;
using MongoDB.Driver.Linq;

...

// follow the mongo set up above

...

// retrieve the entry
var appointment = collection
    .AsQueryable()
    FirstOrDefault(x => x.Id == 12);

if (appointment != .null)
{
  appointment.StartDateTime = new DateTime(2020, 2, 20);
  
  // save the changes
  collection.ReplaceOne(x => x.Id == appointment.Id, appointment); // or preferably, await collection.ReplaceOneAsync(x => x.Id == appointment.Id, appointment);
}

Deleting Data

Well, all good things come to an end and the time would come where you would need to remove an entry from a collection. This perhaps is the simplest operation to perform. Following from the code shown above, if I want to delete the entry with the id of `121. I would write:

using System;
using System.Linq;
using MongoDB.Driver.Linq;

...

// follow the mongo set up above

...

// remove the erring entry
collection.DeleteOne(x => x.Id == 12);

Conclusion

I believe the aims of this guide have been accomplished. You should be able to carry basic CRUD operations on your MongoDB database. If you need to handle some more advanced querying, I would recommend this article.

Cheers.