MongoDB.Driver для C# (.NET): полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

MongoDB.Driver для C# (.NET): полное руководство

1. Что это и зачем нужна

MongoDB.Driver — это официальный, высокопроизводительный и асинхронный драйвер для взаимодействия приложений на платформе .NET (C#, F#, VB.NET) с базой данных MongoDB. Он предоставляет полный набор инструментов для выполнения всех операций CRUD (Create, Read, Update, Delete), управления индексами, агрегации данных, работы с транзакциями и обработки изменений в реальном времени (Change Streams). Драйвер разрабатывается и поддерживается компанией MongoDB Inc., что гарантирует его полную совместимость с последними версиями MongoDB и реализацию всех современных возможностей СУБД.

Зачем нужна эта библиотека? Если вы разрабатываете .NET-приложение (веб-сервис на ASP.NET Core, десктопное приложение на WPF, консольную утилиту или микросервис) и хотите использовать MongoDB в качестве основного или вспомогательного хранилища данных, вам необходим драйвер для установления соединения и обмена данными. MongoDB.Driver абстрагирует сложность сетевого протокола MongoDB (Wire Protocol), предоставляя разработчику удобный, строго типизированный API. Вы работаете с C#-объектами, а драйвер автоматически сериализует их в BSON (двоичный формат MongoDB) и обратно. Это позволяет писать лаконичный, безопасный и производительный код, не вникая в детали низкоуровневого взаимодействия.

Библиотека поддерживает две основные парадигмы работы: синхронную и асинхронную (рекомендуемую). Асинхронные методы (с суффиксом Async) позволяют не блокировать потоки выполнения, что критически важно для масштабируемых серверных приложений. Драйвер также включает в себя LINQ-провайдер, который транслирует LINQ-запросы в синтаксис MongoDB Aggregation Pipeline, что делает код еще более декларативным и привычным для .NET-разработчиков.

2. Установка

Установка производится через менеджер пакетов NuGet. Выполните одну из следующих команд в консоли диспетчера пакетов (Package Manager Console) или в терминале .NET CLI.

Через .NET CLI (рекомендуется):

dotnet add package MongoDB.Driver

Через Package Manager Console (Visual Studio):

Install-Package MongoDB.Driver

Для проектов, использующих Entity Framework Core (опционально):

Существует отдельный провайдер MongoDB.EntityFrameworkCore, но для большинства задач достаточно основного драйвера.

После установки в файл проекта (.csproj) будет добавлена ссылка:

<PackageReference Include="MongoDB.Driver" Version="2.25.0" />

3. Быстрый старт — минимальный рабочий пример

Следующий код подключается к локальному экземпляру MongoDB, получает базу данных "testdb", коллекцию "users", вставляет один документ и выводит его ID в консоль.

using MongoDB.Bson;
using MongoDB.Driver;

// 1. Создаем клиент (подключение к серверу)
var client = new MongoClient("mongodb://localhost:27017");

// 2. Получаем базу данных (создается автоматически, если не существует)
var database = client.GetDatabase("testdb");

// 3. Получаем коллекцию (создается автоматически при первой вставке)
var collection = database.GetCollection<BsonDocument>("users");

// 4. Создаем документ
var document = new BsonDocument
{
    { "name", "Alice" },
    { "age", 30 },
    { "city", "New York" }
};

// 5. Вставляем документ (асинхронно)
await collection.InsertOneAsync(document);

// 6. Выводим сгенерированный ID
Console.WriteLine($"Документ вставлен с ID: {document["_id"]}");

// 7. Читаем все документы из коллекции
var allUsers = await collection.Find(new BsonDocument()).ToListAsync();
foreach (var user in allUsers)
{
    Console.WriteLine(user.ToJson());
}

4. Основные методы/функции/классы

4.1 MongoClient

Сигнатура: public MongoClient(string connectionString)

Что делает: Создает экземпляр клиента для подключения к кластеру MongoDB. Connection string содержит адрес сервера, параметры аутентификации и настройки пула соединений.

var client = new MongoClient("mongodb://user:password@localhost:27017/admin?retryWrites=true");
var database = client.GetDatabase("production");

4.2 IMongoDatabase.GetCollection

Сигнатура: IMongoCollection<TDocument> GetCollection<TDocument>(string name, MongoCollectionSettings settings = null)

Что делает: Возвращает объект коллекции, типизированный указанным типом TDocument. Если коллекция не существует, она будет создана автоматически при первой записи в нее.

// Работа с типизированными документами
public class Product
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

var collection = database.GetCollection<Product>("products");

4.3 IMongoCollection.InsertOneAsync

Сигнатура: Task InsertOneAsync(TDocument document, InsertOneOptions options = null, CancellationToken cancellationToken = default)

Что делает: Асинхронно вставляет один документ в коллекцию. Если документ не содержит поле _id, драйвер автоматически сгенерирует ObjectId.

var product = new Product { Name = "Laptop", Price = 1200.50m };
await collection.InsertOneAsync(product);
Console.WriteLine($"Inserted product with ID: {product.Id}");

4.4 IMongoCollection.Find

Сигнатура: IFindFluent<TDocument, TProjection> Find(FilterDefinition<TDocument> filter, FindOptions options = null)

Что делает: Выполняет поиск документов, соответствующих заданному фильтру. Возвращает объект IFindFluent, который можно дополнительно настроить (сортировка, проекция, лимит) и затем материализовать вызовом ToListAsync, FirstOrDefaultAsync и т.д.

// Поиск всех продуктов дороже 1000
var filter = Builders<Product>.Filter.Gt(p => p.Price, 1000);
var expensiveProducts = await collection.Find(filter).ToListAsync();

// Поиск одного продукта по имени
var laptop = await collection.Find(p => p.Name == "Laptop").FirstOrDefaultAsync();

4.5 IMongoCollection.ReplaceOneAsync

Сигнатура: Task<ReplaceOneResult> ReplaceOneAsync(FilterDefinition<TDocument> filter, TDocument replacement, ReplaceOptions options = null, CancellationToken cancellationToken = default)

Что делает: Заменяет первый документ, соответствующий фильтру, на новый документ. Поле _id заменяемого документа сохраняется, если оно не указано явно в новом документе.

var filter = Builders<Product>.Filter.Eq(p => p.Name, "Laptop");
var updatedProduct = new Product { Name = "Gaming Laptop", Price = 2000.00m };
var result = await collection.ReplaceOneAsync(filter, updatedProduct);
Console.WriteLine($"Matched: {result.MatchedCount}, Modified: {result.ModifiedCount}");

4.6 IMongoCollection.UpdateOneAsync / UpdateManyAsync

Сигнатура: Task<UpdateResult> UpdateOneAsync(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, UpdateOptions options = null, CancellationToken cancellationToken = default)

Что делает: Обновляет поля существующего документа (документов) без замены всего документа. UpdateOneAsync обновляет первый найденный, UpdateManyAsync — все соответствующие фильтру.

// Увеличить цену всех продуктов на 10%
var filter = Builders<Product>.Filter.Empty;
var update = Builders<Product>.Update.Mul(p => p.Price, 1.10m);
var result = await collection.UpdateManyAsync(filter, update);
Console.WriteLine($"Modified {result.ModifiedCount} documents");

4.7 IMongoCollection.DeleteOneAsync / DeleteManyAsync

Сигнатура: Task<DeleteResult> DeleteOneAsync(FilterDefinition<TDocument> filter, CancellationToken cancellationToken = default)

Что делает: Удаляет один или несколько документов, соответствующих фильтру. DeleteOneAsync удаляет первый найденный документ, DeleteManyAsync — все.

// Удалить все продукты дешевле 100
var filter = Builders<Product>.Filter.Lt(p => p.Price, 100);
var result = await collection.DeleteManyAsync(filter);
Console.WriteLine($"Deleted {result.DeletedCount} documents");

4.8 IMongoCollection.Aggregate

Сигнатура: IAggregateFluent<TResult> Aggregate(PipelineDefinition<TDocument, TResult> pipeline, AggregateOptions options = null)

Что делает: Выполняет конвейер агрегации (Aggregation Pipeline) для сложной обработки данных: группировка, сортировка, преобразование, вычисление статистик.

// Группировка продуктов по имени и подсчет среднего возраста
var pipeline = collection.Aggregate()
    .Group(new BsonDocument 
    { 
        { "_id", "$name" }, 
        { "avgPrice", new BsonDocument("$avg", "$price") },
        { "count", new BsonDocument("$sum", 1) }
    })
    .Sort(new BsonDocument("avgPrice", -1));

var results = await pipeline.ToListAsync();
foreach (var result in results)
{
    Console.WriteLine(result.ToJson());
}

4.9 IMongoDatabase.CreateCollectionAsync

Сигнатура: Task CreateCollectionAsync(string name, CreateCollectionOptions options = null, CancellationToken cancellationToken = default)

Что делает: Явно создает коллекцию с заданными параметрами (например, с указанием размера для capped collection, настройками валидации схемы).

var options = new CreateCollectionOptions 
{ 
    Capped = true, 
    MaxSize = 1024 * 1024, // 1 MB
    MaxDocuments = 1000 
};
await database.CreateCollectionAsync("logs", options);

4.10 IMongoCollection.Indexes.CreateOneAsync

Сигнатура: Task<string> CreateOneAsync(CreateIndexModel<TDocument> model, CreateOneIndexOptions options = null, CancellationToken cancellationToken = default)

Что делает: Создает индекс на коллекции для ускорения запросов. Можно создавать составные, уникальные, текстовые и геопространственные индексы.

// Создать уникальный индекс по полю Name
var indexModel = new CreateIndexModel<Product>(
    Builders<Product>.IndexKeys.Ascending(p => p.Name),
    new CreateIndexOptions { Unique = true }
);
await collection.Indexes.CreateOneAsync(indexModel);

5. Реальный практический пример (100-200 строк кода)

Разработаем простую консольную программу для управления каталогом книг в библиотеке. Программа будет поддерживать добавление, поиск, обновление и удаление книг, а также вывод статистики по жанрам.

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Book
{
    public ObjectId Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public string Genre { get; set; }
    public int Year { get; set; }
    public decimal Price { get; set; }
    public bool IsAvailable { get; set; } = true;
}

public class LibraryManager
{
    private readonly IMongoCollection<Book> _books;

    public LibraryManager(string connectionString, string databaseName, string collectionName)
    {
        var client = new MongoClient(connectionString);
        var database = client.GetDatabase(databaseName);
        _books = database.GetCollection<Book>(collectionName);
        
        // Создаем индексы для ускорения поиска
        var indexKeys = Builders<Book>.IndexKeys.Ascending(b => b.Author).Ascending(b => b.Genre);
        var indexModel = new CreateIndexModel<Book>(indexKeys);
        _books.Indexes.CreateOneAsync(indexModel).Wait();
    }

    public async Task AddBookAsync(Book book)
    {
        await _books.InsertOneAsync(book);
        Console.WriteLine($"Книга '{book.Title}' добавлена с ID: {book.Id}");
    }

    public async Task<List<Book>> SearchByAuthorAsync(string author)
    {
        var filter = Builders<Book>.Filter.Regex(b => b.Author, new BsonRegularExpression(author, "i"));
        return await _books.Find(filter).ToListAsync();
    }

    public async Task<List<Book>> SearchByGenreAsync(string genre)
    {
        var filter = Builders<Book>.Filter.Eq(b => b.Genre, genre);
        return await _books.Find(filter).ToListAsync();
    }

    public async Task<bool> UpdatePriceAsync(ObjectId bookId, decimal newPrice)
    {
        var filter = Builders<Book>.Filter.Eq(b => b.Id, bookId);
        var update = Builders<Book>.Update.Set(b => b.Price, newPrice);
        var result = await _books.UpdateOneAsync(filter, update);
        return result.ModifiedCount > 0;
    }

    public async Task<bool> DeleteBookAsync(ObjectId bookId)
    {
        var filter = Builders<Book>.Filter.Eq(b => b.Id,                    

Рекомендаций