Barış Kısır

NoSQL Foundations: Mastering MongoDB Integration in .NET

26 Jun 2017

The Evolution of Data Storage: Why MongoDB?

As applications evolve to handle semi-structured data and massive scale, document-oriented NoSQL databases like MongoDB have become indispensable. Unlike traditional relational databases, MongoDB stores data in dynamic, JSON-like documents (BSON), allowing for rapid schema evolution and superior horizontal scaling.

Essential Infrastructure Configuration

Before orchestrating your .NET application, ensure your local MongoDB environment is initialized.

  1. Deployment: Download MongoDB Community Server.
  2. Initialization: Establish a data directory and initialize the mongod daemon.
  3. Visualization: Utilize tools like Compass or Studio 3T (formerly Robomongo) for database administration and visual query building.

Integrating MongoDB with .NET

The official MongoDB .NET driver provides a feature-rich, strongly-typed interface for executing CRUD operations.

Installation via NuGet

Install-Package MongoDB.Driver

Architecting the Domain Model

In MongoDB, every document requires an _id field. We utilize attributes to map our C# property names to the underlying BSON document structure.

public class Employee
{
    [BsonId]
    public ObjectId Id { get; set; }

    [BsonElement("firstName")]
    public string Name { get; set; }

    [BsonElement("lastName")]
    public string Surname { get; set; }

    [BsonElement("officeEmail")]
    public string Email { get; set; }
}

Establishing the Repository Layer

The following MongoDBRepository encapsulates the logic for establishing a connection and performing structured queries.

public class EmployeeRepository
{
    private readonly IMongoCollection<Employee> _collection;

    public EmployeeRepository()
    {
        // Initializing the MongoDB context and targeting the 'hr' database
        var client = new MongoClient("mongodb://127.0.0.1:27017");
        var database = client.GetDatabase("hr");
        _collection = database.GetCollection<Employee>("records");
    }

    public async Task<List<Employee>> GetAllAsync() => 
        await _collection.Find(_ => true).ToListAsync();

    public async Task CreateAsync(Employee employee) => 
        await _collection.InsertOneAsync(employee);

    public async Task UpdateAsync(ObjectId id, Employee updatedEmployee) => 
        await _collection.ReplaceOneAsync(e => e.Id == id, updatedEmployee);

    public async Task RemoveAsync(ObjectId id) => 
        await _collection.DeleteOneAsync(e => e.Id == id);
}

Modern Query Paradigms

  • Typed Filters: Leverage LINQ expressions (e.g., _collection.Find(x => x.Name == "Kemal")) for compile-time safety.
  • Asynchronous Orchestration: Always utilize the *Async methods to ensure your application remains responsive during I/O operations.
  • Projection: Optimize performance by projecting only the necessary fields using .Project(e => new { e.Name, e.Email }).

Deep Dive: Explore the full implementation and advanced query patterns on GitHub.