Permalink
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upusing System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Linq.Expressions; | |
using System.Threading.Tasks; | |
using Nessos.LinqOptimizer.Base; | |
using Nessos.LinqOptimizer.Core; | |
using QExpr = Nessos.LinqOptimizer.Core.QueryExpr; | |
namespace Nessos.LinqOptimizer.CSharp | |
{ | |
/// <summary> | |
/// Provides a set of static methods for querying objects that implement IQueryExpr. | |
/// </summary> | |
public static class Extensions | |
{ | |
/// <summary> | |
/// Enables the optimization of a query. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam> | |
/// <param name="source">An IEnumerable to convert to an IQueryExpr.</param> | |
/// <returns>A query that returns the elements of the source sequence.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> AsQueryExpr<TSource>(this IEnumerable<TSource> source) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(CoreHelpers.AsQueryExpr(source, typeof(TSource))); | |
} | |
#region Compile methods | |
/// <summary> | |
/// Compiles a query to optimized code that can by invoked using a Func. | |
/// </summary> | |
/// <param name="query">The query to compile</param> | |
/// <returns>A Func containing optimized code.</returns> | |
public static Func<TQuery> Compile<TQuery>(this IQueryExpr<TQuery> query) | |
{ | |
return CoreHelpers.Compile<TQuery>(query.Expr, CSharpExpressionOptimizer.Optimize); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code that can by invoked using a Func. <para/> | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <param name="query">The query to compile</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A Func containing optimized code.</returns> | |
public static Func<TQuery> Compile<TQuery>(this IQueryExpr<TQuery> query, bool enableNonPublicMemberAccess) | |
{ | |
return CoreHelpers.Compile<TQuery>(query.Expr, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code that can by invoked using a Func. | |
/// </summary> | |
/// <param name="query">The query to compile</param> | |
/// <returns>A Func containing optimized code.</returns> | |
public static Action Compile(this IQueryExpr query) | |
{ | |
return CoreHelpers.Compile(query.Expr, CSharpExpressionOptimizer.Optimize); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code that can by invoked using a Func.<para/> | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <param name="query">The query to compile</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A Func containing optimized code.</returns> | |
public static Action Compile(this IQueryExpr query, bool enableNonPublicMemberAccess) | |
{ | |
return CoreHelpers.Compile(query.Expr, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
#endregion | |
#region Run methods | |
/// <summary> | |
/// Compiles a query to optimized code, runs the code and returns the result. | |
/// </summary> | |
/// <param name="query">The query to run.</param> | |
/// <returns>The result of the query.</returns> | |
public static TQuery Run<TQuery>(this IQueryExpr<TQuery> query) | |
{ | |
return query.Compile<TQuery>().Invoke(); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code, runs the code and returns the result. <para/> | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <param name="query">The query to run.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>The result of the query.</returns> | |
public static TQuery Run<TQuery>(this IQueryExpr<TQuery> query, bool enableNonPublicMemberAccess) | |
{ | |
return query.Compile<TQuery>(enableNonPublicMemberAccess).Invoke(); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code, runs the code and returns the result. | |
/// </summary> | |
/// <param name="query">The query to run.</param> | |
/// <returns>The result of the query.</returns> | |
public static void Run(this IQueryExpr query) | |
{ | |
query.Compile().Invoke(); | |
} | |
/// <summary> | |
/// Compiles a query to optimized code, runs the code and returns the result.<para/> | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <param name="query">The query to run.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>The result of the query.</returns> | |
public static void Run(this IQueryExpr query, bool enableNonPublicMemberAccess) | |
{ | |
query.Compile(enableNonPublicMemberAccess).Invoke(); | |
} | |
#endregion | |
#region Compiled Funcs | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T">The type of the query parameter.</typeparam> | |
/// <typeparam name="TResult">The type of the query.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Func<T, TResult> Compile<T, TResult>(this Expression<Func<T, IQueryExpr<TResult>>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Func<T, TResult>)CoreHelpers.CompileTemplateVariadic<TResult>(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="TResult">The type of the query.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Func<T1, T2, TResult> Compile<T1, T2, TResult>(this Expression<Func<T1, T2, IQueryExpr<TResult>>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Func<T1, T2, TResult>)CoreHelpers.CompileTemplateVariadic<TResult>(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <typeparam name="TResult">The type of the query.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Func<T1, T2, T3, TResult> Compile<T1, T2, T3, TResult>(this Expression<Func<T1, T2, T3, IQueryExpr<TResult>>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Func<T1, T2, T3, TResult>)CoreHelpers.CompileTemplateVariadic<TResult>(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <typeparam name="T4">The type of the fourth query parameter.</typeparam> | |
/// <typeparam name="TResult">The type of the query.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Func<T1, T2, T3, T4, TResult> Compile<T1, T2, T3, T4, TResult>(this Expression<Func<T1, T2, T3, T4, IQueryExpr<TResult>>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Func<T1, T2, T3, T4, TResult>)CoreHelpers.CompileTemplateVariadic<TResult>(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <typeparam name="T4">The type of the fourth query parameter.</typeparam> | |
/// <typeparam name="T5">The type of the fifth query parameter.</typeparam> | |
/// <typeparam name="TResult">The type of the query.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Func<T1, T2, T3, T4, T5, TResult> Compile<T1, T2, T3, T4, T5, TResult>(this Expression<Func<T1, T2, T3, T4, IQueryExpr<TResult>>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Func<T1, T2, T3, T4, T5, TResult>)CoreHelpers.CompileTemplateVariadic<TResult>(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
#endregion | |
#region Compiled Actions | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T">The type of the query parameter.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Action<T> Compile<T>(this Expression<Func<T, IQueryExpr>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Action<T>)CoreHelpers.CompileActionTemplateVariadic(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Action<T1, T2> Compile<T1, T2>(this Expression<Func<T1, T2, IQueryExpr>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Action<T1, T2>)CoreHelpers.CompileActionTemplateVariadic(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Action<T1, T2, T3> Compile<T1, T2, T3>(this Expression<Func<T1, T2, T3, IQueryExpr>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Action<T1, T2, T3>)CoreHelpers.CompileActionTemplateVariadic(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <typeparam name="T4">The type of the fourth query parameter.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Action<T1, T2, T3, T4> Compile<T1, T2, T3, T4>(this Expression<Func<T1, T2, T3, T4, IQueryExpr>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Action<T1, T2, T3, T4>)CoreHelpers.CompileActionTemplateVariadic(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
/// <summary> | |
/// Precompiles a parameterized query to optimized code that can by invoked using a Func. | |
/// <b>Warning</b> : Enabling non-public member access might lead to performance degradation. | |
/// </summary> | |
/// <typeparam name="T1">The type of the first query parameter.</typeparam> | |
/// <typeparam name="T2">The type of the second query parameter.</typeparam> | |
/// <typeparam name="T3">The type of the third query parameter.</typeparam> | |
/// <typeparam name="T4">The type of the fourth query parameter.</typeparam> | |
/// <typeparam name="T5">The type of the fifth query parameter.</typeparam> | |
/// <param name="template">The parameterized query.</param> | |
/// <param name="enableNonPublicMemberAccess">Enable or not non public member access from the compiled code.</param> | |
/// <returns>A delegate to the optimized query.</returns> | |
public static Action<T1, T2, T3, T4, T5> Compile<T1, T2, T3, T4, T5>(this Expression<Func<T1, T2, T3, T4, IQueryExpr>> template, bool enableNonPublicMemberAccess = false) | |
{ | |
var param = template.Parameters.ToArray(); | |
var query = CSharpExpressionOptimizer.ToQueryExpr(template.Body); | |
return (Action<T1, T2, T3, T4, T5>)CoreHelpers.CompileActionTemplateVariadic(param, query, CSharpExpressionOptimizer.Optimize, enableNonPublicMemberAccess); | |
} | |
#endregion | |
#region Combinators | |
/// <summary> | |
/// Creates a new query that projects each element of a sequence into a new form. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of the query.</typeparam> | |
/// <typeparam name="TResult">The type of the value returned by selector.</typeparam> | |
/// <param name="query">A query whose values to invoke a transform function on.</param> | |
/// <param name="selector">A transform function to apply to each element.</param> | |
/// <returns>A query whose elements will be the result of invoking the transform function on each element of source.</returns> | |
public static IQueryExpr<IEnumerable<TResult>> Select<TSource, TResult>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, TResult>> selector) | |
{ | |
return new QueryExpr<IEnumerable<TResult>>(QExpr.NewTransform(selector, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that projects each element of a sequence into a new form by incorporating the element's index. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TResult">The type of the value returned by selector.</typeparam> | |
/// <param name="query">A query whose values to invoke a transform function on.</param> | |
/// <param name="selector">A transform function to apply to each source element; the second parameter of the function represents the index of the source element.</param> | |
/// <returns>A query whose elements will be the result of invoking the transform function on each element of source.</returns> | |
public static IQueryExpr<IEnumerable<TResult>> Select<TSource, TResult>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, int, TResult>> selector) | |
{ | |
return new QueryExpr<IEnumerable<TResult>>(QExpr.NewTransformIndexed(selector, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that filters a sequence of values based on a predicate. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">An query whose values to filter.</param> | |
/// <param name="predicate">A function to test each element for a condition.</param> | |
/// <returns>A query that contains elements from the input query that satisfy the condition.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> Where<TSource>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, bool>> predicate) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewFilter(predicate, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of query.</typeparam> | |
/// <param name="query">An query whose values to filter.</param> | |
/// <param name="predicate">A function to test each source element for a condition; the second parameter of the function represents the index of the source element.</param> | |
/// <returns>A query that contains elements from the input query that satisfy the condition.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> Where<TSource>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, int, bool>> predicate) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewFilterIndexed(predicate, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TAcc">The type of the accumulator value.</typeparam> | |
/// <param name="query">An query whose values are used to aggregate over.</param> | |
/// <param name="seed">The initial accumulator value.</param> | |
/// <param name="func">An accumulator function to be invoked on each element.</param> | |
/// <returns>A query that returns the final accumulator value.</returns> | |
public static IQueryExpr<TAcc> Aggregate<TSource, TAcc>(this IQueryExpr<IEnumerable<TSource>> query, TAcc seed, Expression<Func<TAcc, TSource, TAcc>> func) | |
{ | |
return new QueryExpr<TAcc>(QExpr.NewAggregate(Expression.Constant(seed), func, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that computes the sum of a sequence of Double values. | |
/// </summary> | |
/// <param name="query">A query whose sequence of Double values to calculate the sum of.</param> | |
/// <returns>A query that returns the sum of the values in the sequence.</returns> | |
public static IQueryExpr<double> Sum(this IQueryExpr<IEnumerable<double>> query) | |
{ | |
return new QueryExpr<double>(QExpr.NewSum(query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that computes the sum of a sequence of Long values. | |
/// </summary> | |
/// <param name="query">A query whose sequence of Long values to calculate the sum of.</param> | |
/// <returns>A query that returns the sum of the values in the sequence.</returns> | |
public static IQueryExpr<long> Sum(this IQueryExpr<IEnumerable<long>> query) | |
{ | |
return new QueryExpr<long>(QExpr.NewSum(query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that computes the sum of a sequence of int values. | |
/// </summary> | |
/// <param name="query">A query whose sequence of int values to calculate the sum of.</param> | |
/// <returns>A query that returns the sum of the values in the sequence.</returns> | |
public static IQueryExpr<int> Sum(this IQueryExpr<IEnumerable<int>> query) | |
{ | |
return new QueryExpr<int>(QExpr.NewSum(query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that returns the number of elements in a sequence. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">A query whose elements will be count.</param> | |
/// <returns>A query that returns the number of elements in the input sequence.</returns> | |
public static IQueryExpr<int> Count<TSource>(this IQueryExpr<IEnumerable<TSource>> query) | |
{ | |
return new QueryExpr<int>(QExpr.NewCount(query.Expr)); | |
} | |
/// <summary> | |
/// Creates a new query that projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TResult">The type of the elements of the sequence returned by selector.</typeparam> | |
/// <param name="query">A query whose values to project.</param> | |
/// <param name="selector">A transform function to apply to each element.</param> | |
/// <returns>A query whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.</returns> | |
public static IQueryExpr<IEnumerable<TResult>> SelectMany<TSource, TResult>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, IEnumerable<TResult>>> selector) | |
{ | |
var paramExpr = selector.Parameters.Single(); | |
var bodyExpr = selector.Body; | |
var nested = Tuple.Create(paramExpr, CSharpExpressionOptimizer.ToQueryExpr(bodyExpr)); | |
return new QueryExpr<IEnumerable<TResult>>(QExpr.NewNestedQuery(nested, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a query that projects each element of a sequence to an IEnumerable, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TCol">The type of the intermediate elements collected by collectionSelector.</typeparam> | |
/// <typeparam name="TResult">The type of the elements of the sequence returned by selector.</typeparam> | |
/// <param name="query">A query whose values to project.</param> | |
/// <param name="collectionSelector">A transform function to apply to each element of the input sequence.</param> | |
/// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param> | |
/// <returns>A query whose elements are the result of invoking the one-to-many transform function on each element of the input sequence and the result selector function on each element therein.</returns> | |
public static IQueryExpr<IEnumerable<TResult>> SelectMany<TSource, TCol, TResult>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, IEnumerable<TCol>>> collectionSelector, Expression<Func<TSource, TCol, TResult>> resultSelector) | |
{ | |
var paramExpr = collectionSelector.Parameters.Single(); | |
var bodyExpr = collectionSelector.Body; | |
var nested = Tuple.Create(paramExpr, CSharpExpressionOptimizer.ToQueryExpr(bodyExpr)); | |
return new QueryExpr<IEnumerable<TResult>>(QExpr.NewNestedQueryTransform(nested, resultSelector, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a query that returns a specified number of contiguous elements from the start of a sequence. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">The query to return elements from.</param> | |
/// <param name="count">The number of elements to return.</param> | |
/// <returns>A query that returns a sequence containing the specified number of elements from the start of the input sequence.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> Take<TSource>(this IQueryExpr<IEnumerable<TSource>> query, int count) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewTake(Expression.Constant(count), query.Expr)); | |
} | |
/// <summary> | |
/// Creates a query that returns elements from a sequence as long as a specified condition is true, and then skips the remaining elements. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">The query to return elements from.</param> | |
/// <param name="predicate">A function to test each element for a condition.</param> | |
/// <returns>A query that contains the elements from the input sequence that occur before the element at which the test no longer passes.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> TakeWhile<TSource>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, bool>> predicate) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewTakeWhile(predicate, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a query that bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">The query to return elements from.</param> | |
/// <param name="predicate">A function to test each element for a condition.</param> | |
/// <returns>A query that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> SkipWhile<TSource>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, bool>> predicate) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewSkipWhile(predicate, query.Expr)); | |
} | |
/// <summary> | |
/// A query that bypasses a specified number of elements in a sequence and then returns the remaining elements. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">A query to return elements from.</param> | |
/// <param name="count">The number of elements to skip before returning the remaining elements.</param> | |
/// <returns>A query that returns a sequence containing the elements that occur after the specified index in the input sequence.</returns> | |
public static IQueryExpr<IEnumerable<TSource>> Skip<TSource>(this IQueryExpr<IEnumerable<TSource>> query, int count) | |
{ | |
return new QueryExpr<IEnumerable<TSource>>(QExpr.NewSkip(Expression.Constant(count), query.Expr)); | |
} | |
/// <summary> | |
/// A query that performs the specified action on each element of the source query. | |
/// </summary> | |
/// <param name="query">An query to return elements from.</param> | |
/// <param name="action">The Action delegate to perform on each element of the query.</param> | |
/// <returns>A query that performs the action on each element.</returns> | |
public static IQueryExpr ForEach<TSource>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Action<TSource>> action) | |
{ | |
return new QueryExprVoid(QExpr.NewForEach(action, query.Expr)); | |
} | |
/// <summary> | |
/// A query that groups the elements of a sequence according to a specified key selector function. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam> | |
/// <param name="query">A query whose elements to group.</param> | |
/// <param name="keySelector">A function to extract the key for each element.</param> | |
/// <returns>A query where each IGrouping element contains a sequence of objects and a key.</returns> | |
public static IQueryExpr<IEnumerable<IGrouping<TKey, TSource>>> GroupBy<TSource, TKey>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, TKey>> keySelector) | |
{ | |
return new QueryExpr<IEnumerable<IGrouping<TKey,TSource>>>(QExpr.NewGroupBy(keySelector, query.Expr, typeof(IGrouping<TKey,TSource>))); | |
} | |
/// <summary> | |
/// Creates a query that sorts the elements of a sequence in ascending order according to a key. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam> | |
/// <param name="query">A query whose values to order.</param> | |
/// <param name="keySelector">A function to extract a key from an element.</param> | |
/// <returns>A query whose elements are sorted according to a key.</returns> | |
public static IQueryExpr<IOrderedEnumerable<TSource>> OrderBy<TSource, TKey>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, TKey>> keySelector) | |
{ | |
return new QueryExpr<IOrderedEnumerable<TSource>>(QExpr.AddOrderBy(keySelector, Order.Ascending, query.Expr)); | |
} | |
/// <summary> | |
/// Creates a query that sorts the elements of a sequence in descending order according to a key. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam> | |
/// <param name="query">A query whose values to order.</param> | |
/// <param name="keySelector">A function to extract a key from an element.</param> | |
/// <returns>A query whose elements are sorted in descending according to a key.</returns> | |
public static IQueryExpr<IOrderedEnumerable<TSource>> OrderByDescending<TSource, TKey>(this IQueryExpr<IEnumerable<TSource>> query, Expression<Func<TSource, TKey>> keySelector) | |
{ | |
return new QueryExpr<IOrderedEnumerable<TSource>>(QExpr.AddOrderBy(keySelector, Order.Descending, query.Expr)); | |
} | |
/// <summary> | |
/// A query that returns a List from an sequence of values. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">The query to create a List from.</param> | |
/// <returns>A query that contains elements from the input sequence in a List form.</returns> | |
public static IQueryExpr<List<TSource>> ToList<TSource>(this IQueryExpr<IEnumerable<TSource>> query) | |
{ | |
return new QueryExpr<List<TSource>>(QExpr.NewToList(query.Expr)); | |
} | |
/// <summary> | |
/// A query that returns an array from an sequence of values. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <param name="query">The query to create an array from.</param> | |
/// <returns>A query that contains elements from the input sequence in an array form.</returns> | |
public static IQueryExpr<TSource[]> ToArray<TSource>(this IQueryExpr<IEnumerable<TSource>> query) | |
{ | |
return new QueryExpr<TSource[]>(QExpr.NewToArray(query.Expr)); | |
} | |
/// <summary> | |
/// Performs a subsequent ordering of the elements of a sequence in ascending order according to a key. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam> | |
/// <param name="query">A query whose values to order.</param> | |
/// <param name="keySelector">A function to extract a key from an element.</param> | |
/// <returns>A query whose elements are sorted according to a key.</returns> | |
public static IQueryExpr<IOrderedEnumerable<TSource>> ThenBy<TSource, TKey>(this IQueryExpr<IOrderedEnumerable<TSource>> query, Expression<Func<TSource, TKey>> keySelector) | |
{ | |
return new QueryExpr<IOrderedEnumerable<TSource>>(QExpr.AddOrderBy(keySelector, Order.Ascending, query.Expr)); | |
} | |
/// <summary> | |
/// Performs a subsequent ordering of the elements of a sequence in descending order according to a key. | |
/// </summary> | |
/// <typeparam name="TSource">The type of the elements of source.</typeparam> | |
/// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam> | |
/// <param name="query">A query whose values to order.</param> | |
/// <param name="keySelector">A function to extract a key from an element.</param> | |
/// <returns>A query whose elements are sorted according to a key.</returns> | |
public static IQueryExpr<IOrderedEnumerable<TSource>> ThenByDescending<TSource, TKey>(this IQueryExpr<IOrderedEnumerable<TSource>> query, Expression<Func<TSource, TKey>> keySelector) | |
{ | |
return new QueryExpr<IOrderedEnumerable<TSource>>(QExpr.AddOrderBy(keySelector, Order.Descending, query.Expr)); | |
} | |
/// <summary> | |
/// A query that generates a sequence by mimicking a for loop. | |
/// </summary> | |
/// <typeparam name="TState">State type.</typeparam> | |
/// <typeparam name="TResult">Result sequence element type.</typeparam> | |
/// <param name="initialState">Initial state of the generator loop.</param> | |
/// <param name="condition">Loop condition.</param> | |
/// <param name="iterate">State update function to run after every iteration of the generator loop.</param> | |
/// <param name="resultSelector">Result selector to compute resulting sequence elements.</param> | |
/// <returns>A query whose elements are obtained by running the generator loop, yielding computed elements.</returns> | |
public static IQueryExpr<IEnumerable<TResult>> Generate<TState, TResult>(TState initialState, Expression<Func<TState, bool>> condition, Expression<Func<TState, TState>> iterate, Expression<Func<TState, TResult>> resultSelector) | |
{ | |
return new QueryExpr<IEnumerable<TResult>>(QExpr.NewGenerate(Expression.Constant(initialState), condition, iterate, resultSelector)); | |
} | |
#endregion | |
} | |
} |