using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using ZeroFramework.IdentityServer.API.Tenants; namespace ZeroFramework.IdentityServer.API.IdentityStores { public class ApplicationDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor, ICurrentTenant currentTenant) : IdentityDbContext(options) { private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor; private readonly ICurrentTenant _currentTenant = currentTenant; protected override void OnModelCreating(ModelBuilder builder) { builder.Entity(b => { b.Property(u => u.TenantUserName).HasMaxLength(256).IsRequired(); b.Property(u => u.DisplayName).HasMaxLength(256); }); builder.Entity(b => { b.Property(u => u.TenantRoleName).HasMaxLength(256).IsRequired(); b.Property(r => r.DisplayName).HasMaxLength(256); }); builder.Entity(b => { b.HasKey(t => t.Id); b.HasIndex(t => t.NormalizedName).IsUnique(); b.ToTable("AspNetTenants", "dbo"); b.Property(t => t.ConcurrencyStamp).IsConcurrencyToken(); b.Property(t => t.Name).HasMaxLength(256); b.Property(t => t.NormalizedName).HasMaxLength(256); b.Property(t => t.DisplayName).HasMaxLength(256); b.HasMany().WithOne().HasForeignKey(tc => tc.TenantId); b.HasMany().WithOne().HasForeignKey(r => r.TenantId); b.HasMany().WithOne().HasForeignKey(u => u.TenantId); }); builder.Entity(b => { b.HasKey(tc => tc.Id); b.ToTable("AspNetTenantClaims", "dbo"); }); foreach (IMutableEntityType entityType in builder.Model.GetEntityTypes()) { if (entityType.ClrType.IsAssignableTo(typeof(IMultiTenant))) { builder.Entity(entityType.ClrType).AddQueryFilter(t => IgnoreQueryFilters(_httpContextAccessor) || t.TenantId == _currentTenant.Id); } } base.OnModelCreating(builder); } protected virtual bool IgnoreQueryFilters(IHttpContextAccessor httpContextAccessor) { Endpoint? endpoint = _httpContextAccessor?.HttpContext?.GetEndpoint(); if (endpoint != null && endpoint.Metadata.Any(item => item is ApiControllerAttribute)) { return false; } return true; } } }