Fix tenant ID handling and query filtering logic.

Replaced direct query filter setup with a dedicated method for cleaner and more readable tenant ID filtering logic. Removed unnecessary dependencies and improved code consistency by aligning naming conventions and simplifying expressions.
This commit is contained in:
Sipke Schoorstra 2025-05-16 21:57:49 +02:00
parent d254ba3385
commit 237b22bf0f
No known key found for this signature in database
GPG key ID: 5C10502B28A4268F
2 changed files with 32 additions and 17 deletions

View file

@ -19,7 +19,7 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
};
protected IServiceProvider ServiceProvider { get; }
private readonly ElsaDbContextOptions? _elsaDbContextOptions;
private readonly ElsaDbContextOptions? elsaDbContextOptions;
public string? TenantId { get; set; }
/// <summary>
@ -41,10 +41,10 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
protected ElsaDbContextBase(DbContextOptions options, IServiceProvider serviceProvider) : base(options)
{
ServiceProvider = serviceProvider;
_elsaDbContextOptions = options.FindExtension<ElsaDbContextOptionsExtension>()?.Options;
elsaDbContextOptions = options.FindExtension<ElsaDbContextOptionsExtension>()?.Options;
// ReSharper disable once VirtualMemberCallInConstructor
Schema = !string.IsNullOrWhiteSpace(_elsaDbContextOptions?.SchemaName) ? _elsaDbContextOptions.SchemaName : ElsaSchema;
Schema = !string.IsNullOrWhiteSpace(elsaDbContextOptions?.SchemaName) ? elsaDbContextOptions.SchemaName : ElsaSchema;
var tenantAccessor = serviceProvider.GetService<ITenantAccessor>();
var tenantId = tenantAccessor?.Tenant?.Id;
@ -63,11 +63,11 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (!string.IsNullOrWhiteSpace(Schema))
if (!string.IsNullOrWhiteSpace(Schema))
modelBuilder.HasDefaultSchema(Schema);
var additionalConfigurations = _elsaDbContextOptions?.GetModelConfigurations(this);
var additionalConfigurations = elsaDbContextOptions?.GetModelConfigurations(this);
additionalConfigurations?.Invoke(modelBuilder);
using var scope = ServiceProvider.CreateScope();
@ -75,7 +75,7 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
foreach (var entityType in modelBuilder.Model.GetEntityTypes().ToList())
{
foreach (var handler in entityTypeHandlers)
foreach (var handler in entityTypeHandlers)
handler.Handle(this, modelBuilder, entityType);
}
}

View file

@ -1,9 +1,7 @@
using System.Linq.Expressions;
using Elsa.Common.Entities;
using Elsa.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
namespace Elsa.EntityFrameworkCore.EntityHandlers;
@ -15,15 +13,32 @@ public class SetTenantIdFilter : IEntityModelCreatingHandler
/// <inheritdoc />
public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType)
{
if (!entityType.ClrType.IsAssignableTo(typeof(Entity)))
if (!typeof(Entity).IsAssignableFrom(entityType.ClrType))
return;
var tenantId = dbContext.TenantId.NullIfEmpty();
var parameter = Expression.Parameter(entityType.ClrType);
Expression<Func<Entity, bool>> filterExpr = entity => entity.TenantId == tenantId;
var body = ReplacingExpressionVisitor.Replace(filterExpr.Parameters[0], parameter, filterExpr.Body);
var lambdaExpression = Expression.Lambda(body, parameter);
modelBuilder
.Entity(entityType.ClrType)
.HasQueryFilter(CreateTenantFilterExpression(dbContext, entityType.ClrType));
}
entityType.SetQueryFilter(lambdaExpression);
private LambdaExpression CreateTenantFilterExpression(ElsaDbContextBase dbContext, Type clrType)
{
var parameter = Expression.Parameter(clrType, "e");
// e => EF.Property<string>(e, "TenantId") == this.TenantId
var tenantIdProperty = Expression.Call(
typeof(EF),
nameof(EF.Property),
[typeof(string)],
parameter,
Expression.Constant("TenantId"));
var tenantIdOnContext = Expression.Property(
Expression.Constant(dbContext),
nameof(ElsaDbContextBase.TenantId));
var body = Expression.Equal(tenantIdProperty, tenantIdOnContext);
return Expression.Lambda(body, parameter);
}
}