Пользователь указывает c строку подключения в EntityFramework. net core - PullRequest
0 голосов
/ 08 апреля 2020

Мы разрабатываем мультитенантное приложение, используя. net core и EntityFramework. Будет один развернутый экземпляр API, но несколько DBS (одна DB на пользователя). Итак, какова лучшая стратегия изменения строки подключения к БД в зависимости от контекста пользователя.

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Установите строку подключения в методе OnConfiguring, равном DbContext, вызвав UseSqlServer или любой другой вашей базой данных. В этом методе вам нужна ссылка на какой-либо сервис, который предоставит пользовательское соединение c. Для этого, IMO, лучший способ - внедрить IHttpContextAccessor через класс DbContext, а внутри OnConfiguring использовать его для получения HttpContext и всех зарегистрированных сервисов. Вы не должны забывать регистрироваться IHttpContextAccessor по звонку на AddHttpContextAccessor. Пример кода:

//MyContext
public class MyContext : DbContext
{
    public MyContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : base(options)
    {
        this.HttpContextAccessor = httpContextAccessor;
    }

    protected IHttpContextAccessor HttpContextAccessor { get; }

    protected override void OnConfiguring(DbContextOptionsBuilder builder)
    {
        var context = this.HttpContextAccessor.HttpContext;
        var userService = context.RequestServices<IUserService>();
        var user = context.User.Identity.Name;
        var connectionString = userService.GetConnectionString(user);

        builder.UseSqlServer(connectionString);

        base.OnConfiguring(builder);
    }
}


//Startup.ConfigureServices
services.AddHttpContextAccessor();
services.AddDbContext<MyContext>();

Обратите внимание, что IUserService - это просто какая-то служба, которую вы должны реализовать, которая будет возвращать строку подключения для данного пользователя.

0 голосов
/ 08 апреля 2020

Я думаю, вы должны реализовать что-то вроде этой ссылки https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation

или как в этом примере

using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;

public interface IDbContextFactory 
{
    Task<TContext> Create<TContext>(int userId);
}

public class DbContextFactory : IDbContextFactory
{
    public DbContextFactory()
    {

    }

    public async Task<TContext> Create<TContext>(int userId)
        where TContext: DbContext, new()
    {
        //TODO: build connectionString using SqlConnectionStringBuilder and replace the values in []
        var connectionStringBuilder = new SqlConnectionStringBuilder("Application Name=SSCommitmentService;")
        {
            DataSource = $"tcp:[dbServer],1433",
            InitialCatalog = "[catalog]",
            UserID = "[sqlUserid]",
            Password = "[sqlPassword]"
        };
        var options = new DbContextOptionsBuilder<TContext>();
        //TODO: configure the DbContextOptions to use the Provider (Sql, MySql, etc)
        options.UseSqlServer(connectionStringBuilder.ConnectionString);
        //TODO: instantiate the required dbcontext
        var dbContext = new TContext(options.Options);
        return dbContext;
    }
}
...