48 lines
1.6 KiB
C#
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);
|
|
}
|
|
}
|