Dynamic Connection Strings for Multi-Tenant ASP.NET Apps

October 16, 2025 · 6 min

Building a multi-tenant SaaS application presents unique challenges, especially when it comes to data isolation. One of the most common and robust approaches is the “database-per-tenant” model, where each customer’s data resides in its own dedicated database. This ensures strong security and simplifies scaling.

The core problem, however, is telling your application which database to connect to for any given HTTP request. A static connection string in appsettings.json won’t work. We need a dynamic, request-aware mechanism. This is where ASP.NET Core middleware shines. By intercepting requests early, we can identify the tenant, retrieve their specific connection string, and configure services for the remainder of the request pipeline.

In this post, we’ll walk through building a middleware-based solution to manage tenant-aware connection strings in an ASP.NET Core application.

The Challenge with Static Configuration

In a typical single-tenant application, you register your DbContext like this:

// Program.cs - The traditional way
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));

This works because the connection string is known at startup and never changes. In a multi-tenant world, the connection string depends on who is making the request, a detail that is only available once the HTTP …

...

Read more

5 EF Core Patterns for Faster ASP.NET Core APIs

September 13, 2025 · 7 min

I once inherited a dashboard page that took over five seconds to load. The API endpoint behind it looked innocent enough, but digging in, I found a classic case of death by a thousand cuts: lazy loading, bloated entities, and chatty database calls. It was a textbook example of default EF Core behavior backfiring under real-world load.

After fixing that mess (and many others like it), I’ve developed a small playbook of go-to optimizations. These aren’t wild, complex tricks. They’re five fundamental patterns that I apply to almost every high-traffic ASP.NET Core project.

Here’s what I do to keep my data layers fast and lean.

1. Ditch Full Entities, Project to DTOs

This one is my golden rule for read queries. If you’re just displaying data, stop loading full-blown EF Core entities.

The problem is that when you pull an entity, EF Core has to hydrate every single property. Even the ones you don’t need. This results in bigger SQL queries that join more tables and pull back way more data than your API client will ever see.

It’s pure waste.

Instead, use Select to project directly into a Data Transfer Object (DTO).

// The slow way
var users = await _context.Users
    .Include(u => u.Profile) // Pulls everything from two tables
    .ToListAsync();

// The fast, clean way
var users = await _context.Users
    .Select(u => new UserSummaryDto 
    {
        Id = u.Id,
        Name = u.Name,
        Email = u.Email
    })
    .ToListAsync();

On a …

...

Read more