Files
Academic-Affairs-System/src/Jiaowu.Api/Infrastructure/Persistence/QueryableCollectionExtensions.cs
T
2026-07-26 10:19:46 +08:00

48 lines
1.6 KiB
C#

using System.Linq.Expressions;
namespace Jiaowu.Api.Infrastructure.Persistence;
public static class QueryableCollectionExtensions
{
public static IQueryable<TEntity> WhereIn<TEntity, TValue>(
this IQueryable<TEntity> source,
IEnumerable<TValue> values,
Expression<Func<TEntity, TValue>> valueSelector)
{
var predicate = BuildPredicate(values, valueSelector, Expression.OrElse, false);
return source.Where(predicate);
}
public static IQueryable<TEntity> WhereNotIn<TEntity, TValue>(
this IQueryable<TEntity> source,
IEnumerable<TValue> values,
Expression<Func<TEntity, TValue>> valueSelector)
{
var predicate = BuildPredicate(values, valueSelector, Expression.AndAlso, true);
return source.Where(predicate);
}
private static Expression<Func<TEntity, bool>> BuildPredicate<TEntity, TValue>(
IEnumerable<TValue> values,
Expression<Func<TEntity, TValue>> valueSelector,
Func<Expression, Expression, BinaryExpression> combine,
bool negate)
{
Expression? body = null;
foreach (var value in values.Distinct())
{
Expression comparison = Expression.Equal(
valueSelector.Body,
Expression.Constant(value, typeof(TValue)));
if (negate)
comparison = Expression.Not(comparison);
body = body is null ? comparison : combine(body, comparison);
}
body ??= Expression.Constant(negate);
return Expression.Lambda<Func<TEntity, bool>>(
body,
valueSelector.Parameters);
}
}