Работа с базами данных в C#: PostgreSQL и MongoDB на практике

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

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

Начать курс

Работа с базами данных в C#: PostgreSQL и MongoDB на практике

Работа с базами данных — одна из ключевых задач любого backend-разработчика. В экосистеме C# (.NET) разработчику доступны сотни драйверов и ORM, но наиболее востребованными остаются реляционные СУБД (PostgreSQL) и документо-ориентированные NoSQL-решения (MongoDB). В этой статье мы на практических примерах разберём, как подключаться к обеим базам, выполнять CRUD-операции и выбирать подходящий инструмент под конкретную задачу.

1. PostgreSQL в C#: подключение и CRUD через Npgsql

Для работы с PostgreSQL в .NET используется библиотека Npgsql — высокопроизводительный ADO.NET-провайдер. Установим её через NuGet:

dotnet add package Npgsql

1.1. Подключение к базе данных

Строка подключения для локального сервера PostgreSQL выглядит так:

string connectionString = "Host=localhost;Port=5432;Database=testdb;Username=postgres;Password=your_password";

Создадим класс-помощник для работы с БД:

using Npgsql;

public class PostgresService
{
    private readonly string _connectionString;

    public PostgresService(string connectionString)
    {
        _connectionString = connectionString;
    }

    public async Task InsertUserAsync(string name, int age)
    {
        await using var conn = new NpgsqlConnection(_connectionString);
        await conn.OpenAsync();

        var cmd = new NpgsqlCommand(
            "INSERT INTO users (name, age) VALUES (@name, @age)", conn);
        cmd.Parameters.AddWithValue("name", name);
        cmd.Parameters.AddWithValue("age", age);

        await cmd.ExecuteNonQueryAsync();
    }

    public async Task<List<User>> GetAllUsersAsync()
    {
        var users = new List<User>();

        await using var conn = new NpgsqlConnection(_connectionString);
        await conn.OpenAsync();

        var cmd = new NpgsqlCommand("SELECT id, name, age FROM users", conn);
        await using var reader = await cmd.ExecuteReaderAsync();

        while (await reader.ReadAsync())
        {
            users.Add(new User
            {
                Id = reader.GetInt32(0),
                Name = reader.GetString(1),
                Age = reader.GetInt32(2)
            });
        }

        return users;
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

1.2. Использование Entity Framework Core с PostgreSQL

Для более удобной работы с реляционными данными используйте ORM Entity Framework Core с провайдером Npgsql.EntityFrameworkCore.PostgreSQL:

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL

Пример модели и контекста:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql("Host=localhost;Database=testdb;Username=postgres;Password=your_password");
    }
}

Теперь CRUD-операции становятся тривиальными:

using (var db = new AppDbContext())
{
    // Create
    db.Users.Add(new User { Name = "Alice", Age = 30 });
    db.SaveChanges();

    // Read
    var users = db.Users.ToList();

    // Update
    var user = db.Users.First();
    user.Age = 31;
    db.SaveChanges();

    // Delete
    db.Users.Remove(user);
    db.SaveChanges();
}

2. MongoDB в C#: работа с документами через официальный драйвер

MongoDB — документная NoSQL база, где данные хранятся в формате BSON. Для C# существует мощный официальный драйвер MongoDB.Driver.

2.1. Установка и подключение

dotnet add package MongoDB.Driver

Подключение к локальному серверу:

var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("testdb");
var collection = database.GetCollection<BsonDocument>("users");

2.2. CRUD-операции с типизированными классами

Рекомендуется работать не с BsonDocument, а с POCO-классами:

public class User
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public List<string> Tags { get; set; }
}

Пример сервиса:

using MongoDB.Driver;

public class MongoService
{
    private readonly IMongoCollection<User> _usersCollection;

    public MongoService()
    {
        var client = new MongoClient("mongodb://localhost:27017");
        var database = client.GetDatabase("testdb");
        _usersCollection = database.GetCollection<User>("users");
    }

    public async Task InsertUserAsync(User user)
    {
        await _usersCollection.InsertOneAsync(user);
    }

    public async Task<List<User>> GetAllUsersAsync()
    {
        return await _usersCollection.Find(_ => true).ToListAsync();
    }

    public async Task<User> GetUserByNameAsync(string name)
    {
        return await _usersCollection.Find(u => u.Name == name).FirstOrDefaultAsync();
    }

    public async Task UpdateUserAgeAsync(string name, int newAge)
    {
        var filter = Builders<User>.Filter.Eq(u => u.Name, name);
        var update = Builders<User>.Update.Set(u => u.Age, newAge);
        await _usersCollection.UpdateOneAsync(filter, update);
    }

    public async Task DeleteUserAsync(string name)
    {
        await _usersCollection.DeleteOneAsync(u => u.Name == name);
    }
}

3. PostgreSQL vs MongoDB: когда что выбирать?

Выбор между реляционной и документной базой — не техническая, а архитектурная задача. Рассмотрим критерии:

  • Структура данных: если данные строго типизированы, нормализованы и требуют сложных JOIN — выбирайте PostgreSQL. Если данные слабоструктурированы или часто меняют схему — MongoDB.
  • Транзакции и ACID: PostgreSQL полностью поддерживает ACID-транзакции. MongoDB с версии 4.0 также поддерживает транзакции, но с ограничениями.
  • Гибкость схемы: MongoDB позволяет хранить в одной коллекции документы с разными полями — это удобно для прототипирования.
  • Производительность: MongoDB быстрее на опера

Блоги

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