using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; using System.Reflection; namespace ZeroFramework.DeviceCenter.Infrastructure.Specifications.Extensions { public static class SearchExtension { /// /// Filters by applying an 'SQL LIKE' operation to it. /// /// The type being queried against. /// The sequence of /// /// /// Selector, the property to apply the SQL LIKE against. /// SearchTerm, the value to use for the SQL LIKE. /// /// /// public static IQueryable Search(this IQueryable source, IEnumerable<(Expression> selector, string searchTerm)> criterias) { Expression? expr = null; var parameter = Expression.Parameter(typeof(T), "x"); foreach (var (selector, searchTerm) in criterias) { if (selector == null || string.IsNullOrEmpty(searchTerm)) { continue; } PropertyInfo? propertyInfo = typeof(EF).GetProperty(nameof(EF.Functions)); if (propertyInfo is null) { continue; } var functions = Expression.Property(null, propertyInfo); var like = typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.Like), new Type[] { functions.Type, typeof(string), typeof(string) }); if (like is null) { continue; } var propertySelector = ParameterReplacerVisitor.Replace(selector, selector.Parameters[0], parameter); var expression = (propertySelector as LambdaExpression)?.Body; if (expression is null) { continue; } var likeExpression = Expression.Call(null, like, functions, expression, Expression.Constant(searchTerm)); expr = expr == null ? likeExpression : Expression.OrElse(expr, likeExpression); } return expr == null ? source : source.Where(Expression.Lambda>(expr, parameter)); } } }