< Summary

Information
Class: Nabs.Persistence.TenantableDbContext<T>
Assembly: Nabs.Persistence
File(s): /home/runner/work/Nabs/Nabs/src/Nabs.Persistence/TenantableDbContext.cs
Tag: 90_14636759620
Line coverage
100%
Covered lines: 27
Uncovered lines: 0
Coverable lines: 27
Total lines: 65
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Tenants()100%11100%
OnModelCreating(...)100%66100%
SaveChanges()100%11100%
SaveChangesAsync()100%11100%
SetTenantId()100%1212100%

File(s)

/home/runner/work/Nabs/Nabs/src/Nabs.Persistence/TenantableDbContext.cs

#LineLine coverage
 1namespace Nabs.Persistence;
 2
 3public abstract class TenantableDbContext<TTenantEntity>(
 4    DbContextOptions options,
 5    IApplicationContext applicationContext)
 16    : DbContext(options), ITenantableDbContext
 7    where TTenantEntity : class, ITenantEntity
 8{
 19    public IApplicationContext ApplicationContext { get; } = applicationContext;
 10
 111    public DbSet<TTenantEntity> Tenants => Set<TTenantEntity>();
 12
 13    protected override void OnModelCreating(ModelBuilder modelBuilder)
 14    {
 115        base.OnModelCreating(modelBuilder);
 16
 317        foreach (var entityType in modelBuilder.Model.GetEntityTypes())
 18        {
 119            if (typeof(ITenantableEntity).IsAssignableFrom(entityType.ClrType))
 20            {
 121                entityType.AddTenantEntityQueryFilter(this);
 22            }
 23
 124            if (typeof(TTenantEntity) == entityType.ClrType)
 25            {
 126                Expression<Func<TTenantEntity, bool>> filter = entity =>
 127                    EF.Property<Guid>(entity, "Id") == ApplicationContext.TenantContext.TenantId;
 28
 129                entityType.SetQueryFilter(filter);
 30            }
 31        }
 132    }
 33
 34    public override int SaveChanges()
 35    {
 136        SetTenantId();
 137        return base.SaveChanges();
 38    }
 39
 40    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
 41    {
 142        SetTenantId();
 143        return await base.SaveChangesAsync(cancellationToken);
 144    }
 45
 46    private void SetTenantId()
 47    {
 148        var entries = ChangeTracker.Entries()
 249                        .Where(e => e.Entity is ITenantableEntity &&
 250                                    e.State == EntityState.Added ||
 251                                    e.State == EntityState.Modified);
 152        if (entries.Any())
 53        {
 154            if (ApplicationContext.TenantContext.TenantId == Guid.Empty)
 55            {
 156                throw new InvalidOperationException("TenantId is not set.");
 57            }
 58        }
 59
 360        foreach (var entry in entries)
 61        {
 162            entry.Property(nameof(TenantId)).CurrentValue = ApplicationContext.TenantContext.TenantId;
 63        }
 164    }
 65}