public static IQueryable GroupJoin(this IQueryable outer, IQueryable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] values) { Check.NotNull(outer, nameof(outer)); Check.NotNull(inner, nameof(inner)); Check.NotEmpty(outerKeySelector, nameof(outerKeySelector)); Check.NotEmpty(innerKeySelector, nameof(innerKeySelector)); Check.NotEmpty(resultSelector, nameof(resultSelector)); Type innerElementType = inner.AsQueryable().ElementType; var outerParameter = Expression.Parameter(outer.ElementType, "outer"); var innerParameter = Expression.Parameter(innerElementType, "inner"); var groupParameter = Expression.Parameter(typeof(IEnumerable <>) .MakeGenericType(innerElementType), "group"); var outerLambda = DynamicExpression.ParseLambda(new[] { outerParameter }, null, outerKeySelector, values); var innerLambda = DynamicExpression.ParseLambda(new[] { innerParameter }, outerLambda.Body.Type, innerKeySelector, values); var resultLambda = DynamicExpression.ParseLambda(new[] { outerParameter, groupParameter }, null, resultSelector, values); return(outer.Provider.CreateQuery(Expression.Call(typeof(Queryable), "GroupJoin", new[] { outer.ElementType, innerElementType, outerLambda.Body.Type, resultLambda.Body.Type }, outer.Expression, Expression.Constant(inner), Expression.Quote(outerLambda), Expression.Quote(innerLambda), Expression.Quote(resultLambda)))); }
public static IQueryable Join(this IQueryable outer, IQueryable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) { Check.NotNull(outer, nameof(outer)); Check.NotNull(inner, nameof(inner)); Check.NotEmpty(outerSelector, nameof(outerSelector)); Check.NotEmpty(innerSelector, nameof(innerSelector)); Check.NotEmpty(resultsSelector, nameof(resultsSelector)); var outerParameter = Expression.Parameter(outer.ElementType, "outer"); var innerParameter = Expression.Parameter(inner.ElementType, "inner"); LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(new[] { outerParameter }, null, outerSelector, values); LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(new[] { innerParameter }, null, innerSelector, values); ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(inner.ElementType, "inner") }; LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values); return(outer.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Join", new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type }, outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda)))); }
public static (IEnumerable <object> results, Type resultType) LeftJoinWithResultType(this IEnumerable outer, IEnumerable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] values) { Type innerElementType = inner.AsQueryable().ElementType; var outerParameter = Expression.Parameter(outer.AsQueryable().ElementType, "outer"); var groupParameter = Expression.Parameter(typeof(IEnumerable <>) .MakeGenericType(innerElementType), "group"); LambdaExpression resultLambda = DynamicExpression.ParseLambda(new[] { outerParameter, groupParameter }, null, resultSelector, values); return(outer.LeftJoin(inner, outerKeySelector, innerKeySelector, resultSelector, values), resultLambda.Body.Type); }
public static IQueryable <object> LeftJoin(this IEnumerable outer, IEnumerable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] values) { Check.NotNull(outer, nameof(outer)); Check.NotNull(inner, nameof(inner)); Check.NotEmpty(outerKeySelector, nameof(outerKeySelector)); Check.NotEmpty(innerKeySelector, nameof(innerKeySelector)); Check.NotEmpty(resultSelector, nameof(resultSelector)); Type innerElementType = inner.AsQueryable().ElementType; var outerParameter = Expression.Parameter(outer.AsQueryable().ElementType, "outer"); var innerParameter = Expression.Parameter(innerElementType, "inner"); var groupParameter = Expression.Parameter(typeof(IEnumerable <>) .MakeGenericType(innerElementType), "group"); LambdaExpression outerLambda = DynamicExpression.ParseLambda(new[] { outerParameter }, null, outerKeySelector, values); LambdaExpression innerLambda = DynamicExpression.ParseLambda(new[] { innerParameter }, outerLambda.Body.Type, innerKeySelector, values); LambdaExpression resultLambda = DynamicExpression.ParseLambda(new[] { outerParameter, groupParameter }, null, resultSelector, values); MethodInfo method = typeof(Enumerable).GetMethods().First(c => c.Name == "ToLookup") .MakeGenericMethod(new[] { innerElementType, outerLambda.Body.Type }); MethodInfo containsMethod = typeof(DynamicObjectExtensions).GetMethod(nameof(DynamicContans), BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(new[] { outerLambda.Body.Type, innerElementType }); var lookup = Expression.Lambda(Expression.Call(method, Expression.Constant(inner), innerLambda)).Compile().DynamicInvoke(); List <object> retList = new List <object>(); foreach (var outerElement in outer) { var key = outerLambda.Compile().DynamicInvoke(outerElement); var val = Expression.Lambda(Expression.Call(containsMethod, Expression.Constant(lookup), Expression.Convert(Expression.Constant(key), outerLambda.Body.Type))) .Compile() .DynamicInvoke(); retList.Add(resultLambda.Compile().DynamicInvoke(outerElement, val)); } return((IQueryable <object>)System.Linq.Dynamic.Core.DynamicQueryableExtensions.OfType(retList.AsQueryable(), resultLambda.Body.Type)); }
public static IEnumerable <GroupResult> GroupByMany <TElement>( this IEnumerable <TElement> elements, string totalcolumn, params string[] groupSelectors) { var selectors = new List <Func <TElement, object> >(groupSelectors.Length); foreach (var selector in groupSelectors) { LambdaExpression l = DynamicExpressionParser.ParseLambda( typeof(TElement), typeof(object), selector); selectors.Add((Func <TElement, object>)l.Compile()); } return(elements.GroupByMany(totalcolumn, selectors.ToArray())); }