← Назад к вопросам

Как подключаешься к БД?

1.3 Junior🔥 252 комментариев
#Entity Framework и ORM#Базы данных и SQL

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подключение к базе данных в C# Backend

В современных C# приложениях подключение к базе данных осуществляется через ADO.NET или ORM-фреймворки, чаще всего Entity Framework Core. Вот основные подходы с примерами:

1. Прямое подключение через ADO.NET (базовый уровень)

Для прямого подключения используется класс SqlConnection:

using System.Data.SqlClient;
// Или для .NET Core/5+: using Microsoft.Data.SqlClient;

public class DatabaseService
{
    private readonly string _connectionString;
    
    public DatabaseService(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public void ConnectAndQuery()
    {
        using (var connection = new SqlConnection(_connectionString))
        {
            try
            {
                connection.Open();
                Console.WriteLine("Подключение установлено!");
                
                using (var command = new SqlCommand("SELECT * FROM Users", connection))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Console.WriteLine($"User: {reader["Username"]}");
                        }
                    }
                }
            }
            catch (SqlException ex)
            {
                Console.WriteLine($"Ошибка подключения: {ex.Message}");
            }
        }
    }
}

2. Использование Entity Framework Core (рекомендуемый подход)

Entity Framework Core - это современный ORM от Microsoft:

// Контекст базы данных
public class ApplicationDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Order> Orders { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // Способ 1: Прямое указание строки подключения
        optionsBuilder.UseSqlServer("Server=localhost;Database=MyDb;Trusted_Connection=True;");
        
        // Способ 2: Через конфигурацию (рекомендуется)
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();
            
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
    }
}

// Регистрация в DI-контейнере (Startup.cs или Program.cs)
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

3. Конфигурация строки подключения

Строка подключения должна храниться в конфигурационных файлах:

appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost\\SQLEXPRESS;Database=MyAppDb;Trusted_Connection=True;MultipleActiveResultSets=true;",
    "ReadOnlyConnection": "Server=readonly-server;Database=MyAppDb;User Id=reader;Password=secure_password;"
  }
}

4. Лучшие практики подключения

Использование Dependency Injection:

public class UserRepository : IUserRepository
{
    private readonly ApplicationDbContext _context;
    
    public UserRepository(ApplicationDbContext context)
    {
        _context = context;
    }
    
    public async Task<User> GetUserByIdAsync(int id)
    {
        return await _context.Users.FindAsync(id);
    }
}

Управление жизненным циклом подключения:

  • Для ADO.NET: Всегда используйте using для SqlConnection
  • Для EF Core: Инжектируйте DbContext через конструктор
  • Используйте async/await для асинхронных операций:
public async Task<List<User>> GetUsersAsync()
{
    using (var connection = new SqlConnection(_connectionString))
    {
        await connection.OpenAsync();
        var result = await connection.QueryAsync<User>("SELECT * FROM Users");
        return result.ToList();
    }
}

Обработка ошибок и resilient connections:

public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> operation, int maxRetries = 3)
{
    var retryCount = 0;
    while (true)
    {
        try
        {
            return await operation();
        }
        catch (SqlException ex) when (ex.Number == -2 || ex.Number == 1205) // Таймаут или deadlock
        {
            if (retryCount >= maxRetries) throw;
            retryCount++;
            await Task.Delay(100 * retryCount);
        }
    }
}

5. Современные паттерны подключения

Реализация Unit of Work:

public interface IUnitOfWork : IDisposable
{
    IUserRepository Users { get; }
    IOrderRepository Orders { get; }
    Task<int> CompleteAsync();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly ApplicationDbContext _context;
    
    public UnitOfWork(ApplicationDbContext context)
    {
        _context = context;
        Users = new UserRepository(_context);
        Orders = new OrderRepository(_context);
    }
    
    public async Task<int> CompleteAsync()
    {
        return await _context.SaveChangesAsync();
    }
    
    public void Dispose() => _context.Dispose();
}

6. Безопасность подключения

  • Никогда не хардкодите строки подключения в коде
  • Используйте Managed Identity для облачных сред (Azure, AWS)
  • Реализуйте Secrets Manager для production-сред
  • Используйте раздельные строки подключения для чтения/записи

7. Пример полной настройки в .NET 6+

Program.cs в современном .NET:

var builder = WebApplication.CreateBuilder(args);

// Добавление DbContext с настройками
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection"),
        sqlOptions => 
        {
            sqlOptions.EnableRetryOnFailure(
                maxRetryCount: 5,
                maxRetryDelay: TimeSpan.FromSeconds(30),
                errorNumbersToAdd: null
            );
        }
    );
});

var app = builder.Build();

Ключевые выводы:

  1. Используйте Entity Framework Core для большинства проектов
  2. Храните строки подключения в конфигурационных файлах
  3. Реализуйте Dependency Injection для управления зависимостями
  4. Используйте асинхронные методы для всех операций с БД
  5. Настройте retry policies для устойчивости
  6. Разделяйте read/write подключения для масштабирования
  7. Следуйте принципам репозитория и Unit of Work для поддерживаемости кода

Эти подходы обеспечивают надежное, безопасное и производительное подключение к базам данных в C# приложениях.