private static Expression GetWherePredicateValueEnumerablePropertyExpression( [NotNull] PropertyInfo property, [NotNull] ParameterExpression parameter, [NotNull] IQueryPredicate <QueryPredicateValue> predicate, [NotNull] IQueryPredicateValue predicateValue) { var c = Expression.PropertyOrField(parameter, predicate.ColumnCode.Split('.')[0]); // list property on parent var a = property.PropertyType.GetGenericArguments()[0]; // list property on parent: item type var p = Expression.Parameter(a, "c"); // comparison on list item type: left var v = GetWherePredicateValueComparisonExpression(a, p, predicate, predicateValue); // comparison on list item type: right var l = Expression.Lambda(v, p); // comparison on list item type return(Expression.Call(typeof(Enumerable), "Any", new[] { a }, c, l)); }
private static Expression GetWherePredicateValueComparisonExpression( [NotNull] Type type, [NotNull] Expression parameter, [NotNull] IQueryPredicate <QueryPredicateValue> predicate, [NotNull] IQueryPredicateValue predicateValue) { var code = predicate.ColumnCode.Split('.').Last().Capitalize(); var property = type.GetProperty(code); if (property == null) { throw new QueryPredicateException($"Predicate compares unknown property {code}."); } var value = GetTypedValue(property, predicateValue.Value); switch (predicateValue.CompareUsing) { case QueryPredicateComparison.Equal: return(Expression.Equal(Expression.Property(parameter, property), value)); case QueryPredicateComparison.NotEqual: return(Expression.NotEqual(Expression.Property(parameter, property), value)); case QueryPredicateComparison.LessThan: return(Expression.LessThan(Expression.Property(parameter, property), value)); case QueryPredicateComparison.LessThanOrEqual: return(Expression.LessThanOrEqual(Expression.Property(parameter, property), value)); case QueryPredicateComparison.GreaterThan: return(Expression.GreaterThan(Expression.Property(parameter, property), value)); case QueryPredicateComparison.GreaterThanOrEqual: return(Expression.GreaterThanOrEqual(Expression.Property(parameter, property), value)); case QueryPredicateComparison.StartsWith: case QueryPredicateComparison.EndsWith: case QueryPredicateComparison.Contains: return(property.PropertyType == typeof(string) ? StringPropertyFilter(parameter, property, predicateValue.Value, predicateValue.CompareUsing) : throw new QueryPredicateValueException($"Property '{code}' on type {type.Name} should be of type string to use {predicateValue.CompareUsing} as comparison type.")); default: throw new QueryPredicateValueException($"Predicate value uses unsupported compare type ({predicateValue.CompareUsing})."); } }
private static Expression GetWherePredicateValueComplexPropertyExpression( [NotNull] Type type, [NotNull] PropertyInfo property, [NotNull] ParameterExpression parameter, [NotNull] IQueryPredicate <QueryPredicateValue> predicate, [NotNull] IQueryPredicateValue predicateValue) { Expression body = parameter; foreach (var memberCode in predicate.ColumnCode.Split('.')) { var memberProperty = type.GetProperty(memberCode); if (memberProperty != null && (!IsComparableProperty(memberProperty) && !memberProperty.PropertyType.Implements <IEnumerable>())) { property = memberProperty; body = Expression.PropertyOrField(body, memberCode); } } return(GetWherePredicateValueComparisonExpression(property.PropertyType, body, predicate, predicateValue)); }
/// <summary> /// Gets the expression that represents the supplied <paramref name="predicateValue"/>'s comparison as part of a where clause's <paramref name="predicate"/>. /// </summary> /// <param name="type">The type.</param> /// <param name="parameter">The "left-side" part of a .</param> /// <param name="predicate">A where clause for a (sub)property query.</param> /// <param name="predicateValue">The value the <paramref name="predicate"/>'s property should match with using the <seealso cref="QueryPredicateValue.CompareUsing"/>.</param> /// <returns>A <paramref name="predicate"/>'s single value comparison expression.</returns> /// <exception cref="QueryPredicateException">Predicate compares unknown property {code}.</exception> private static Expression GetWherePredicateValueExpression( [NotNull] Type type, [NotNull] ParameterExpression parameter, [NotNull] IQueryPredicate <QueryPredicateValue> predicate, [NotNull] IQueryPredicateValue predicateValue) { if (predicate.ColumnCode.Contains('.')) { var code = predicate.ColumnCode.Split('.')[0]; var property = type.GetProperty(code); if (property == null) { throw new QueryPredicateException($"Predicate compares unknown property {code}."); } return(property.PropertyType.Implements <IEnumerable>() ? GetWherePredicateValueEnumerablePropertyExpression(property, parameter, predicate, predicateValue) : GetWherePredicateValueComplexPropertyExpression(type, property, parameter, predicate, predicateValue)); } return(GetWherePredicateValueComparisonExpression(type, parameter, predicate, predicateValue)); }