/// <summary> /// Create a dynamic comparison expression for a given property selector, comparison method and reference value. /// </summary> /// <param name="target">The parameter of the query data.</param> /// <param name="selector">The property selector to parse.</param> /// <param name="comparer">The comparison method to use.</param> /// <param name="value">The reference value to compare with.</param> /// <param name="provider">The culture-specific formatting information.</param> /// <returns>The dynamic comparison expression.</returns> public static Expression CreateComparison(ParameterExpression target, string selector, DynamicCompare comparer, string?value, IFormatProvider?provider = null) { if (target is null) { throw new ArgumentNullException(nameof(target)); } if (string.IsNullOrEmpty(selector)) { throw new ArgumentNullException(nameof(selector)); } if (!Enum.IsDefined(typeof(DynamicCompare), comparer)) { throw new ArgumentOutOfRangeException(nameof(comparer)); } var memberAccess = CreateMemberAccess(target, selector); var actualValue = CreateConstant(target, memberAccess, value, provider); return(comparer switch { DynamicCompare.Equal => Expression.Equal(memberAccess, actualValue), DynamicCompare.NotEqual => Expression.NotEqual(memberAccess, actualValue), DynamicCompare.GreaterThan => Expression.GreaterThan(memberAccess, actualValue), DynamicCompare.GreaterThanOrEqual => Expression.GreaterThanOrEqual(memberAccess, actualValue), DynamicCompare.LessThan => Expression.LessThan(memberAccess, actualValue), DynamicCompare.LessThanOrEqual => Expression.LessThanOrEqual(memberAccess, actualValue), _ => Expression.Constant(false), });
/// <summary> /// Create a dynamic where clause for a given property selector, comparison method and reference value. /// </summary> /// <typeparam name="T">The type of the query data.</typeparam> /// <param name="query">The query to filter.</param> /// <param name="selector">The property selector to parse.</param> /// <param name="comparer">The comparison method to use.</param> /// <param name="value">The reference value to compare with.</param> /// <param name="provider">The culture-specific formatting information.</param> /// <returns>The filtered query.</returns> public static IAsyncQueryable <T> Where <T>(this IAsyncQueryable <T> query, string selector, DynamicCompare comparer, string?value, IFormatProvider?provider = null) { if (query is null) { throw new ArgumentNullException(nameof(query)); } if (string.IsNullOrEmpty(selector)) { throw new ArgumentNullException(nameof(selector)); } if (!Enum.IsDefined(typeof(DynamicCompare), comparer)) { throw new ArgumentOutOfRangeException(nameof(comparer)); } var target = Expression.Parameter(typeof(T)); var comparison = DynamicExpression.CreateComparison(target, selector, comparer, value, provider); return(query.Provider.CreateQuery <T>( CreateAsyncWhereClause(target, query.Expression, comparison))); }
public void ShouldFilterByComparison(DynamicCompare comparison, int[] result) { var culture = new CultureInfo("de-AT"); var empty = data.Where("Number", comparison, null); var compare = data.Where("Number", comparison, "222,222", culture); var emptyResult = empty.Cast <Dummy>().Select(d => d.Id).ToArray(); var compareResult = compare.Cast <Dummy>().Select(d => d.Id).ToArray(); var count = comparison == DynamicCompare.NotEqual ? 9 : 0; Assert.Equal(count, emptyResult.Length); Assert.Equal(result, compareResult); }
public void ShouldFilterByComparison(DynamicCompare comparison, int[] result) { var value = (222.222m).ToString(CultureInfo.CurrentCulture); var empty = data.Where("Number", comparison, null); var compare = data.Where("Number", comparison, value); var emptyResult = empty.Cast <Dummy>().Select(d => d.Id).ToArray(); var compareResult = compare.Cast <Dummy>().Select(d => d.Id).ToArray(); var count = comparison == DynamicCompare.NotEqual ? 9 : 0; Assert.Equal(count, emptyResult.Length); Assert.Equal(result, compareResult); }
/// <summary> /// Create a dynamic where clause for a given property selector, comparison method and reference value. /// </summary> /// <param name="query">The query to filter.</param> /// <param name="selector">The property selector to parse.</param> /// <param name="comparer">The comparison method to use.</param> /// <param name="value">The reference value to compare with.</param> /// <returns>The filtered query.</returns> public static IQueryable Where(this IQueryable query, string selector, DynamicCompare comparer, string value) { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (string.IsNullOrEmpty(selector)) { throw new ArgumentNullException(nameof(selector)); } if (!Enum.IsDefined(typeof(DynamicCompare), comparer)) { throw new ArgumentOutOfRangeException(nameof(comparer)); } var target = Expression.Parameter(query.ElementType); return(query.Provider.CreateQuery(CreateWhereClause(target, query.Expression, selector, comparer, value))); }
/// <summary> /// Create a dynamic predicate for a given property selector, comparison method and reference value. /// </summary> /// <typeparam name="T">The type of the query data.</typeparam> /// <param name="selector">The property selector to parse.</param> /// <param name="comparer">The comparison method to use.</param> /// <param name="value">The reference value to compare with.</param> /// <param name="provider">The culture-specific formatting information.</param> /// <returns>The dynamic predicate.</returns> public static Expression <Func <T, bool> > CreatePredicate <T>(string selector, DynamicCompare comparer, string?value, IFormatProvider?provider = null) { if (string.IsNullOrEmpty(selector)) { throw new ArgumentNullException(nameof(selector)); } if (!Enum.IsDefined(typeof(DynamicCompare), comparer)) { throw new ArgumentOutOfRangeException(nameof(comparer)); } var target = Expression.Parameter(typeof(T)); return(Expression.Lambda <Func <T, bool> >( DynamicExpression.CreateComparison(target, selector, comparer, value, provider), target)); }
static Expression CreateComparison(ParameterExpression target, string selector, DynamicCompare comparer, string value) { var memberAccess = CreateMemberAccess(target, selector); var actualValue = CreateConstant(target, memberAccess, value); switch (comparer) { case DynamicCompare.Equal: return(Expression.Equal(memberAccess, actualValue)); case DynamicCompare.NotEqual: return(Expression.NotEqual(memberAccess, actualValue)); case DynamicCompare.GreaterThan: return(Expression.GreaterThan(memberAccess, actualValue)); case DynamicCompare.GreaterThanOrEqual: return(Expression.GreaterThanOrEqual(memberAccess, actualValue)); case DynamicCompare.LessThan: return(Expression.LessThan(memberAccess, actualValue)); case DynamicCompare.LessThanOrEqual: return(Expression.LessThanOrEqual(memberAccess, actualValue)); default: return(Expression.Constant(false)); } }
static Expression CreateWhereClause(ParameterExpression target, Expression expression, string selector, DynamicCompare comparer, string value) { var predicate = Expression.Lambda(CreateComparison(target, selector, comparer, value), target); return(Expression.Call(typeof(Queryable), nameof(Queryable.Where), new[] { target.Type }, expression, Expression.Quote(predicate))); }