Multi-tenant ASP.NET Core 7 - Defensive database context


Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Defensive database context

To make sure that data from different tenants doesn't get mixed in multi-tenant application we can add some defensive behaviour to multi-tenant database context to build additional safety net for application developers.

The following demonstrates defensive database context and it uses the following classes:

  • ITenantProvider - interface for tenant providers,
  • DummyTenantProvider - tenant provider for demo purposes,
  • BaseEntity - base class for all entities,
  • Person - sample entity type for this demo,
  • CrossTenantUpdateException - exception type for operations that use data from multiple tenants,
  • SampleDbContext - defensive database context.

The sample below creates new instance of database context, adds two instances of Person entities that belong to different tenants and then saves changes. If cross-tenant operation exception is thrown then tenant ID-s involved to incident are written out.

Click to run the .NET Core Web app.
ยทusing System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace EFDefensive
public interface ITenantProvider
Guid GetTenantId();
public class DummyTenantProvider : ITenantProvider
public static Guid Tenant1Id = Guid.Parse("51aab199-1482-4f0d-8ff1-5ca0e7bc525a");
public static Guid Tenant2Id = Guid.Parse("ae4e21fa-57cb-4733-b971-fdd14c4c667e");
public Guid GetTenantId()
return Tenant1Id;
public abstract class BaseEntity
public int Id { get; set; }
public Guid TenantId { get; set; }
public class Person : BaseEntity
public string FirstName { get; set; }
public string LastName { get; set; }
public class CrossTenantUpdateException : ApplicationException
public IList<Guid> TenantIds { get; private set; }
public CrossTenantUpdateException(IList<Guid> tenantIds)
TenantIds = tenantIds;
public class SampleDbContext : DbContext
private Guid _tenantId;


Open Source Your Knowledge: become a Contributor and help others learn. Create New Content