private Func <T, bool> GenerateInFilterFunction <T>(InFilterNode node, BaseFilterOperation <T> filterOperation, QueryEngine <T> engine, ICollection <QueryError> errors) { if (node.leaf || node.children == null || node.children.Count == 0) { errors.Add(new QueryError(node.token.position, "InFilter node cannot be a leaf.")); return(null); } var nestedQueryType = GetNestedQueryType(node); if (nestedQueryType == null) { errors.Add(new QueryError(node.token.position, "Could not deduce nested query type. Did you forget to set the nested query handler?")); return(null); } var transformType = node.filter.queryHandlerTransformer.rightHandSideType; var inFilterFunc = typeof(WhereEnumerableFactory) ?.GetMethod("GenerateInFilterFunctionWithTypes", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance) ?.MakeGenericMethod(typeof(T), nestedQueryType, transformType) ?.Invoke(this, new object[] { node, filterOperation, engine, errors }) as Func <T, bool>; if (inFilterFunc == null) { errors.Add(new QueryError(node.token.position, "Could not create filter function with nested query.")); return(null); } return(inFilterFunc); }
private Func <T, bool> GenerateInFilterFunctionWithTypes <T, TNested, TTransform>(InFilterNode node, BaseFilterOperation <T> filterOperation, QueryEngine <T> engine, ICollection <QueryError> errors) { var nestedQueryEnumerable = EnumerableCreator.Create <TNested>(node.children[0], null, errors); if (nestedQueryEnumerable == null) { return(null); } var nestedQueryTransformer = node.filter.queryHandlerTransformer as NestedQueryHandlerTransformer <TNested, TTransform>; if (nestedQueryTransformer == null) { return(null); } var transformerFunction = nestedQueryTransformer.handler; var dynamicFilterOperation = filterOperation as IDynamicFilterOperation <TTransform>; if (dynamicFilterOperation == null) { return(null); } return(o => { foreach (var item in nestedQueryEnumerable) { var transformedValue = transformerFunction(item); dynamicFilterOperation.SetFilterValue(transformedValue); if (filterOperation.Match(o)) { return true; } } return false; }); }