Настроить строку подключения из контроллера (ASP.NET Core MVC 2.1) - PullRequest
0 голосов
/ 02 февраля 2019

Я хотел бы настроить строку подключения от контроллера, но я не нашел никакой функции, чтобы сделать это.

У меня есть:

public class tstController : Controller
{
    private readonly contextTst _context;

    public tstController(contextTst context)
    {
        _context = context;
        _context.Database.**????**
    }
}

Возможно?

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Учитывая тот факт, что вы хотите установить альтернативную строку соединения в конструкторе, можно предположить, что это известное значение.

Нужно решить, как это сделать с DI.Первая подсказка - это код, который генерируется при скаффолдинге контекста:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
//#warning To protect potentially sensitive information in your
// connection string, you should move it out of source code.
// See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
        optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Database=MyDb;Trusted_Connection=True;");
    }
}

Это означает, что вы можете использовать конфигурацию по умолчанию (optionsBuilder.IsConfigured), задав значение при запуске.Но также используйте альтернативную конструкцию.

Код будет выглядеть следующим образом:

public partial class MyContext : DbContext
{
    private readonly string _connectionString;

    public MyContext(DbContextOptions<MyContext> options)
        : base(options)
    {
    }

    public MyContext(IOptions<DbConnectionInfo> dbConnectionInfo)
    {
        _connectionString = dbConnectionInfo.Value.MyContext;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_connectionString);
        }
    }
}

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

public class DbConnectionInfo
{
    public string MyContext { get; set; }
}

Пример appsettings.json:

"ConnectionStrings": {
    "MyContext": "Server=.\\SQLEXPRESS;Database=MyDb;Trusted_Connection=True;"
  },

И зарегистрировать оба при запуске:

services.Configure<DbConnectionInfo>(settings => configuration.GetSection("ConnectionStrings").Bind(settings));
services.AddScoped<MyContext>();

Если вы не хотите читать строку подключения из конфигурации, а скорее установить ее в зависимости от промежуточного программного обеспечения (например, дляарендатора), то вы можете использовать тот же подход.Просто обновите значение до создания контекста.


Обновление:

С внедрением зависимостей вы не создаете объекты самостоятельно, а передаете зарегистрированный объект / службу как параметр.Я выясню, какие объекты нужно создавать и в каком порядке.Точно так же объекты будут удалены DI после использования.

Тот факт, что контроллер «знает» контекст, заключается в том, что DI автоматически добавляет его в качестве параметра.Тот факт, что контекст «знает» DbConnectionInfo, заключается в том, что он зарегистрирован в DI.

Если вы хотите изменить DbConnectionInfo, вам нужно добавить его надлежащим образом.В вашем случае вы могли бы сделать что-то вроде этого:

// Added as part of the example
services.AddHttpContextAccessor();
// Replace registration with this line:
services.AddScoped<DbConnectionInfo>();
// Register the DbContext
services.AddScoped<MyContext>();

Где альтернативная версия класса:

public class DbConnectionInfo
{
    public string MyContext { get; set; }

    // Example injecting IHttpContextAccessor
    // On creating this class DI will inject 
    // the HttpContextAccessor as parameter
    public DbConnectionInfo(IHttpContextAccessor httpContextAccessor)
    {
        // Access the current request
        var request = httpContextAccessor.HttpContext.Request;

        // Access the current user (if authenticated)
        var user = httpContextAccessor.HttpContext.User;

        // Now you could get a value from a header, claim,
        // querystring or path and use that to set the value:

        MyContext = "";
    }
 }

И в DbContext небольшое изменение, мы не используемIOptions в этом случае:

public partial class MyContext : DbContext
{
    private readonly string _connectionString;

    public MyContext(DbConnectionInfo dbConnectionInfo)
    {
        _connectionString = dbConnectionInfo.MyContext;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder     optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_connectionString);
        }
    }
}

Теперь для каждого запроса будет задано значение до создания MyContext.

0 голосов
/ 02 февраля 2019

Вы должны зарегистрировать DbContext только во время запуска.

Там только вы должны указать строку подключения.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnectionString")));

    services.AddMvc();
}

Это очень важно, если вы используете внедрение зависимостей (из MSDN) :

контексты Entity Framework Entity Frameworkконтексты должны быть добавлены к контейнеру службы с использованием времени жизни с областью действия.Это обрабатывается автоматически с помощью вызова метода AddDbContext при регистрации контекста базы данных.Службы, использующие контекст базы данных, должны также использовать срок действия области.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...