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

Последнее обновление: 25.11.2023

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

  • Переопределение у класса контекста данных метода OnConfiguring()

  • Передача конфигурации в конструктор базового класса DbContext

Метод OnConfiguring

В предыдущих темах использовался первый метод. Например:

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public ApplicationContext() => Database.EnsureCreated();

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=helloapp.db");
    }
}

В этот метод передается объект класса DbContextOptionsBuilder, который позволяет установить параметры подключения. Для их конфигурации параметров подключения у этого класса определено ряд методов в зависимости от того, какую именно систему баз данных мы собираемся использовать. Например, для установки подключения к SQLite вызывается метод UseSqlite(), в который передается строка подключения.

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

using Microsoft.EntityFrameworkCore;

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public string connectionString;
    public ApplicationContext(string connectionString)
    {
        this.connectionString = connectionString;	// получаем извне строку подключения
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite(connectionString);
    }
}

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

Затем при создании объекта контекста передать строку подключения:

using (ApplicationContext db = new ApplicationContext("Data Source=helloapp.db"))
{
    var users = db.Users.ToList();
    Console.WriteLine("Пользователи:");
    foreach (User user in users)
    {
        Console.WriteLine($"{user.Id}.{user.Name} - {user.Age}");
    }
}

Установка конфигурации в конструкторе

Второй способ предполагает передачу в конструктор базового класса объекта DbContextOptions, который инкапсулирует параметры конфигурации. Для применения этого способа изменим класс контекста следующим образом:

using Microsoft.EntityFrameworkCore;

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public ApplicationContext(DbContextOptions<ApplicationContext> options)
            : base(options)
    {
        Database.EnsureCreated();
    }
}

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

Тогда мы могли бы использовать класс контекста следующим образом:

using Microsoft.EntityFrameworkCore;

var optionsBuilder = new DbContextOptionsBuilder<ApplicationContext>();

var options = optionsBuilder.UseSqlite("Data Source=helloapp.db").Options;

using (ApplicationContext db = new ApplicationContext(options))
{
    var users = db.Users.ToList();
    foreach (User user in users)
        Console.WriteLine($"{user.Id}.{user.Name} - {user.Age}");
}

Здесь опять же применяется метод UseSqlServer класса DbContextOptionsBuilder для создания конфигурации по той же строке подключения. Только результат этой операции - объект DbContextOptions затем передается в контекст данных. А контекст данных далее передает этот параметр в конструктор базового класса.

Файл конфигурации

Оба выше представленных способа вполне работают, однако в том определении, в котором они представлены, они имеют один недостаток - строка подключения жестко определена в коде C#. И было бы неплохо, если бы она была бы определена в каком-нибудь внешнем файле подключения, где мы ее могли бы поменять без перекомпиляции приложения.

Для этого добавим в проект новый файл, который назовем appsettings.json и который будет представлять конфигурацию в формате json.

Определим в этом файле следующий код:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=helloapp.db"
  }
}

Здесь опять же определена наша строка подключения.

Чтобы ее использовать, нам надо добавить в проект через Nuget пакет: Microsoft.Extensions.Configuration.Json. Этот пакет специально предназначен для работы с конфигурацией в формате json.

Если мы работаем в Visual Studio, то для файла в окне свойств установим опции Copy to Output Directory значение "Copy if newer" (или "Copy always")

Файл конфигурации JSON для Entity Framework Core в C#

Для работы с БД возьмем ранее определенный класс контекста:

using Microsoft.EntityFrameworkCore;

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public ApplicationContext(DbContextOptions<ApplicationContext> options)
            : base(options)
    {
        Database.EnsureCreated();
    }
}

Далее в файле Program.cs определим следующий код:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

var builder = new ConfigurationBuilder();
// установка пути к текущему каталогу
builder.SetBasePath(Directory.GetCurrentDirectory());
// получаем конфигурацию из файла appsettings.json
builder.AddJsonFile("appsettings.json");
// создаем конфигурацию
var config = builder.Build();
// получаем строку подключения
var connectionString = config.GetConnectionString("DefaultConnection");

var optionsBuilder = new DbContextOptionsBuilder<ApplicationContext>();
var options = optionsBuilder.UseSqlite(connectionString).Options;

using (ApplicationContext db = new ApplicationContext(options))
{
    var users = db.Users.ToList();
    foreach (User user in users)
        Console.WriteLine($"{user.Id}.{user.Name} - {user.Age}");
}

Для создания конфигурации применяется класс ConfigurationBuilder. Метод AddJsonFile() добавляет все настройки из файла конфигурации. С помощью метода Build() создается объект конфигурации, из которого мы можем получить строку подключения:

string connectionString = config.GetConnectionString("DefaultConnection");

Для получения строки подключения используется ее имя - "DefaultConnection", которое указано в appsettings.json. В остальном работа с контекстом данных будет протекать также.

Установка конфигурации в контексте

Приведенный выше способ позволяет локально при вызове констекста задать файл конфигурации. Но если у нас всего один файл конфигурации, который планируется использовать при всех обращениях к контексту данных, то проще задать его непосредственно в контексте данных:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
 
public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public ApplicationContext() 
        : base()
    {
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var config = new ConfigurationBuilder()
                        .AddJsonFile("appsettings.json")
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .Build();

        optionsBuilder.UseSqlite(config.GetConnectionString("DefaultConnection"));
    }
}
 
public class User
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public int Age { get; set; }
}

В данном случае установка конфигурации производится в методе OnConfiguring() контекста данных. Применение контекста:

using (ApplicationContext db = new ApplicationContext())
{
    var users = db.Users.ToList();
    foreach (User user in users)
        Console.WriteLine($"{user.Id}.{user.Name} - {user.Age}");
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850