Loading [Contrib]/a11y/accessibility-menu.js

Multi-tenant ASP.NET Core 5 - Implementing database per tenant strategy


Implementing database per tenant strategy

It's possible that in multi-tenant web application each tenant has its own database. This example shows how to do it.

We start with some code artifacts needed to build such solution:

  • Tenant class - holds current tenant information like metadata and settings
  • Tenant provider interface - interface that tenant providers implement
  • Tenant provider - dummy tenant provider to return demo tenant
  • Person class - simple entity for demo purposes
public class Tenant
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Host { get; set; }
    public string DatabaseConnectionString { get; set; }

public interface ITenantProvider
    Tenant GetTenant();

public class DummyTenantProvider : ITenantProvider
    private static IList<Tenant> _tenants = new List<Tenant>
        new Tenant { Id = MultitenantDbContext.Tenant1Id, Name = "Imaginary corp", DatabaseConnectionString = "ConnStr1" },
        new Tenant { Id = MultitenantDbContext.Tenant2Id, Name = "The Very Big corp", DatabaseConnectionString = "ConnStr2" },

    public Tenant GetTenant()
        return _tenants.First();

public class Person
    public Guid Id { get; set; }
    public Guid TenantId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

Registering services

Let's register services when web application starts. It's done in ConfigureServices() method of Startup class.

public void ConfigureServices(IServiceCollection services)
    services.AddDbContext<MultitenantDbContext>(o => { });


    services.AddTransient<ITenantProvider, DummyTenantProvider>();

We don't set database connection string here as we want to do it in database context when current tenant is detected.

Building multi-tenant database context

Now it's time to build database context.

public class MultitenantDbContext : DbContext
    public static Guid Tenant1Id = Guid.Parse("51aab199-1482-4f0d-8ff1-5ca0e7bc525a");
    public static Guid Tenant2Id = Guid.Parse("ae4e21fa-57cb-4733-b971-fdd14c4c667e");

    public DbSet<Person> People { get; set; }

    private Tenant _tenant;
    private ILogger<MultitenantDbContext> _logger;

    public MultitenantDbContext(ITenantProvider tenantProvider, ILogger<MultitenantDbContext> logger)
        _tenant = tenantProvider.GetTenant();
        _logger = logger;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        // Comment out for real application

        // Comment in for real applications


    protected override void OnModelCreating(ModelBuilder modelBuilder)

        modelBuilder.Entity<Person>().HasQueryFilter(p => p.TenantId == _tenant.Id);

    public void AddSampleData()
        People.Add(new Person
            Id = Guid.Parse("79865406-e01b-422f-bd09-92e116a0664a"),
            TenantId = Tenant1Id,
            FirstName = "Gunnar",
            LastName = "Peipman"

        People.Add(new Person
            Id = Guid.Parse("d5674750-7f6b-43b9-b91b-d27b7ac13572"),
            TenantId = Tenant2Id,
            FirstName = "John",
            LastName = "Doe"

        People.Add(new Person
            Id = Guid.Parse("e41446f9-c779-4ff6-b3e5-752a3dad97bb"),
            TenantId = Tenant1Id,
            FirstName = "Mary",
            LastName = "Jones"


Check OnConfiguring() method. This is where connection string is set for database provider. First tenant is detected by tenant provider and then tenant specific connection string is used by database context.


Let's run demo that writes out current tenant people and connection string.

Click Run to run the demo
using System.Linq;
using DBPerTenantExample.Models;
using Microsoft.AspNetCore.Mvc;
namespace DBPerTenantExample.Controllers
public class HomeController : Controller
private readonly MultitenantDbContext _context;
private readonly ITenantProvider _provider;


Create your playground on Tech.io
This playground was created on Tech.io, our hands-on, knowledge-sharing platform for developers.
Go to tech.io
codingame x discord
Join the CodinGame community on Discord to chat about puzzle contributions, challenges, streams, blog articles - all that good stuff!
Online Participants