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));
}
}
}