0

We are developing a multitenant app using .net core and EntityFramework. There will be a single deployed instance of APIs but multiple DBS( one DB per user). So what's the best strategy change DB connection string as per-user context.

2
  • What kind of app? Desktop or web? Commented Apr 8, 2020 at 18:56
  • its an API @CaiusJard Commented Apr 8, 2020 at 19:12

2 Answers 2

3

Set the connection string in the OnConfiguring method of DbContext, by calling UseSqlServer, or whatever your database is. In this method, you need to have a reference to some service that will provide the user-specific connection. For this, IMO, the best way is to inject an IHttpContextAccessor through the DbContext class, and, inside OnConfiguring, use it to obtain the HttpContext and all the registered services. You must not forget to register IHttpContextAccessor by a call to AddHttpContextAccessor. Sample code:

//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>();

Note that IUserService is just some service that you must implement that will return the connection string for the given user.

Sign up to request clarification or add additional context in comments.

Comments

-1

I think you should implement something like is in this link https://learn.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation

or like this example

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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.