public static Expression CreateSelection( this QueryableProjectionScope scope, Expression source, Type sourceType) { MethodCallExpression selection = Expression.Call( typeof(Enumerable), nameof(Enumerable.Select), new[] { scope.RuntimeType, scope.RuntimeType }, source, scope.CreateMemberInitLambda()); if (sourceType.IsArray) { return(ToArray(scope, selection)); } if (TryGetSetType(sourceType, out Type? setType)) { return(ToSet(selection, setType)); } return(ToList(scope, selection)); }
public static Expression CreateMemberInit(this QueryableProjectionScope scope) { if (scope.HasAbstractTypes()) { Expression lastValue = Expression.Default(scope.RuntimeType); foreach (KeyValuePair <Type, Queue <MemberAssignment> > val in scope.GetAbstractTypes()) { NewExpression ctor = Expression.New(val.Key); Expression memberInit = Expression.MemberInit(ctor, val.Value); lastValue = Expression.Condition( Expression.TypeIs(scope.Instance.Peek(), val.Key), Expression.Convert(memberInit, scope.RuntimeType), lastValue); } return(lastValue); } else { NewExpression ctor = Expression.New(scope.RuntimeType); return(Expression.MemberInit(ctor, scope.Level.Peek())); } }
private static Expression ToList(QueryableProjectionScope scope, Expression source) { return(Expression.Call( typeof(Enumerable), nameof(Enumerable.ToList), new[] { scope.RuntimeType }, source)); }
public static QueryableProjectionScope AddScope( this QueryableProjectionContext context, Type runtimeType) { var parameterName = "p" + context.Scopes.Count; var closure = new QueryableProjectionScope(runtimeType, parameterName); context.Scopes.Push(closure); return(closure); }
public static Expression CreateMemberInitLambda(this QueryableProjectionScope scope) { return(Expression.Lambda(scope.CreateMemberInit(), scope.Parameter)); }
public static Expression <Func <T, T> > Project <T>(this QueryableProjectionScope scope) { return((Expression <Func <T, T> >)scope.CreateMemberInitLambda()); }