private static IQueryable <TSource> CallGenericWhereAllMethod <TSource>(IQueryable <TSource> source, BaseFilterQuery filter) { var concreteType = typeof(TSource); var property = concreteType.GetProperty(filter.Attribute.InternalAttributeName); try { var propertyValues = filter.PropertyValue.Split(QueryConstants.COMMA); ParameterExpression entity = Expression.Parameter(concreteType, "x"); MemberExpression member; if (filter.IsAttributeOfRelationship) { var relation = Expression.PropertyOrField(entity, filter.Relationship.InternalRelationshipName); // Intercept the call if the relationship is type of "HasMany" if (typeof(IEnumerable).IsAssignableFrom(relation.Type)) { // Create the lambda using "All" extension method var lambda = BuildAllCall <TSource>(entity, relation, relation.Type.GenericTypeArguments[0], filter); //var lambda = Expression.Lambda<Func<TSource, bool>>(callExpr, entity); return(source.Where(lambda)); } member = Expression.Property(relation, filter.Attribute.InternalAttributeName); } else { throw new JsonApiException(400, $" the operator \"{filter.FilterOperation.ToString()}\" can only affect a \"HasMany\" relationship"); } return(null); } catch (FormatException) { throw new JsonApiException(400, $"Could not cast {filter.PropertyValue} to {property.PropertyType.Name}"); } }
public static IQueryable <TSource> Filter <TSource>(this IQueryable <TSource> source, BaseFilterQuery filterQuery) { if (filterQuery == null) { return(source); } if (filterQuery.FilterOperation == FilterOperations.all || filterQuery.FilterOperation == FilterOperations._all_ || filterQuery.FilterOperation == FilterOperations.exclude) { return(CallGenericWhereAllMethod(source, filterQuery)); } if (filterQuery.FilterOperation == FilterOperations.@in || filterQuery.FilterOperation == FilterOperations.nin) { return(CallGenericWhereContainsMethod(source, filterQuery)); } return(CallGenericWhereMethod(source, filterQuery)); }