.NET Core WebApp, несколько доменов, изменяя строку подключения SQL на основе имени хоста, не могут внедрить httpcontext в файл DB Context.cs - PullRequest
1 голос
/ 06 июня 2019

Я использую ядро ​​Azure .NET WebApp, MVC, Entity Framework, созданное в существующей внешней базе данных MS SQL.

Я регистрирую БД при запуске ConfigureServices следующим образом:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer());

И все работает нормально, пока я устанавливаю строку подключения в методе MyDbContext.cs OnConfiguring () следующим образом:

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
                optionsBuilder.UseSqlServer("Server=10.10.10.10;Database=MyDb;user id=username;password=password;");
        } 

Тогда я могу просто в контроллере сказать:

        private readonly MyDbContext _context;
        public HomeController()
        {
            _context = new MyDbContext();
        }

        public IActionResult Index()
        {
            var item = _context.TableName.FirstOrDefault(d => d.Id > 0);
        }

И это прекрасно работает - потоки данных поступают.

Моя проблема заключается в том, что мне нужно изменить строку подключения SQL в зависимости от того, какое имя хоста подключается. Таким образом, либо при запуске ConfigureServices () я могу передать соединение, если смогу установить используемое имя хоста, либо в методе OnConfiguring () файла DB MyDbContext.cs.

Я могу получить имя хоста только из httpcontext, и, насколько я могу судить, это не доступно для запроса при запуске?

Если я попытаюсь внедрить его в файл БД context.cs, например:

    public partial class MyDbContext : DbContext
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public MyDbContext()
        {
        }

        public MyDbContext(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;         // For context/url
        }

        public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor)
            : base(options)
        {
            _httpContextAccessor = httpContextAccessor;         // For context/url
        }

Затем запускается служба линии ConfigureServices services.AddDbContext не может передать httpcontext (он не существует в этот момент?), Ни один из методов конструктора не совпадает - я не могу внедрить IHttpContextAccessor httpContextAccessor в метод контекста БД независимо от того, как я стараюсь!

services.AddDbContext<MyDbContext>(options => options.UseSqlServer("some-connection-string")); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>()); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>(is there way to pass it?); 

Похоже, это не похоже на внедрение его в контроллеры, что прекрасно работает, так как там нет конструктора ...

Любые идеи о том, как я могу найти имя хоста и изменить строку подключения SQL при данной настройке?

По разным причинам это должен быть один WebApp, который, кстати, используют несколько доменов.

редактировать

После бессонной ночи я проснулся и решил просто подключиться ко всем (трем) базам данных, которые мне нужны, а затем решить, какой контекст использовать в контроллере, поскольку у меня есть httpcontext, чтобы решить, какой хост подключается. Это не идеально, но это веб-приложение с небольшим объемом накладных расходов, поэтому я достаточно счастлив, чтобы пойти с ним так. Я думаю, что, возможно, есть / было решение, хотя ...

Ответы [ 2 ]

2 голосов
/ 07 июня 2019

Вот подход, который я использовал для мультитенантных решений (когда клиенты имеют свою собственную базу данных).

Создайте свой контекст с помощью этой сигнатуры конструктора (не нужно OnConfiguring):

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options) { }
}

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

services.AddHttpContextAccessor();
services.AddDbContext<MyDbContext>();

// This registers DbContextOptions<MyDbContext> which will be called when a new
// instance of MyDbContext is created. You could set breakpoints in this method.
services.AddScoped(sp => 
{
    var context = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;

    // your logic to determine connection string or EF provider
    // ...

    var builder = new DbContextOptionsBuilder<MyDbContext>();
    builder.UseSqlServer("connection string");

    return builder.Options;
});
0 голосов
/ 07 июня 2019

HttpContextAccessor больше не подключен по умолчанию. Убедитесь, что вы добавили сервис в вашем ConfigureServices методе. Таким образом вы сможете использовать HttpCOntext внутри ваших классов DbContext.

Ваш DbContext, указанный в этом вопросе, будет в порядке.

public void ConfigureServices(IServiceCollection services)
{
     ...
     services.AddDbContext<MyDbContext>(options => options.UseSqlServer());
     services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
     ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...