Files
tiku-backend.net/Tiku.Infrastructure/Security/DataScopeQueryableExtensions.cs
xiong c497a3ca8d
Some checks failed
ci / release-gate (push) Has been cancelled
清理代码
2026-08-03 12:31:39 +08:00

43 lines
1.7 KiB
C#

using System.Linq.Expressions;
using Tiku.Application.Security;
namespace Tiku.Infrastructure.Security;
internal static class DataScopeQueryableExtensions
{
public static IQueryable<TEntity> ApplyDataScope<TEntity>(
this IQueryable<TEntity> query,
CurrentDataScope scope,
Expression<Func<TEntity, bool>>? selfPredicate,
Expression<Func<TEntity, bool>>? restrictedPredicate)
{
if (scope.Mode == DataScopeMode.All) return query;
Expression<Func<TEntity, bool>>? predicate = null;
if (scope.IncludesSelf && selfPredicate is not null) predicate = selfPredicate;
if (scope.Mode == DataScopeMode.Restricted && restrictedPredicate is not null)
predicate = predicate is null ? restrictedPredicate : OrElse(predicate, restrictedPredicate);
return predicate is null ? query.Where(_ => false) : query.Where(predicate);
}
private static Expression<Func<TEntity, bool>> OrElse<TEntity>(
Expression<Func<TEntity, bool>> left,
Expression<Func<TEntity, bool>> right)
{
var parameter = Expression.Parameter(typeof(TEntity), "entity");
var leftBody = new ReplaceParameterVisitor(left.Parameters[0], parameter).Visit(left.Body)!;
var rightBody = new ReplaceParameterVisitor(right.Parameters[0], parameter).Visit(right.Body)!;
return Expression.Lambda<Func<TEntity, bool>>(Expression.OrElse(leftBody, rightBody), parameter);
}
private sealed class ReplaceParameterVisitor(ParameterExpression source, ParameterExpression target)
: ExpressionVisitor
{
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}
}