/// <summary>
        /// Initializes a new instance of <see cref="WhereExpression"/> filtering the specified source.
        /// </summary>
        /// <param name="source">The source expression to select from.</param>
        public WhereExpression(ASourceExpression source, APredicateExpression predicate)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            Source    = source;
            Predicate = predicate;

            Fields      = new FieldExpressions(this, source.Fields);
            Expressions = new[] { source };
        }
        /// <summary>
        /// Initializes a new instance of <see cref="TableExpression"/>, selecting the specified fields from the specified table.
        /// </summary>
        /// <param name="table">The name of the table in the database to query.</param>
        /// <param name="alias">The alias name the <see cref="TableExpression"/> should expose for other queries.</param>
        public TableExpression(string table, string alias, IEnumerable <string> fields)
        {
            if (string.IsNullOrWhiteSpace(table))
            {
                throw new ArgumentException("Cannot be whitespace.", nameof(table));
            }
            if (string.IsNullOrWhiteSpace(alias))
            {
                throw new ArgumentException("Cannot be whitespace.", nameof(alias));
            }
            if (fields == null)
            {
                throw new ArgumentNullException(nameof(fields));
            }

            Table       = table;
            Alias       = alias;
            Fields      = new FieldExpressions(this, alias, fields);
            Expressions = new ASourceExpression[0];
        }
        /// <summary>
        /// Initializes a new instance of <see cref="JoinExpression"/> with the specified sources.
        /// </summary>
        /// <param name="outer">The outer source expression to aggregate.</param>
        /// <param name="inner">The inner source expression to aggregate.</param>
        /// <param name="predicate">The optional predicate to condition the join on.</param>
        /// <param name="fields">The fields to select from the sources. If null, all fields are selected.</param>
        /// <param name="joinType">The type of join to perform.</param>
        public JoinExpression(ASourceExpression outer, ASourceExpression inner, APredicateExpression predicate = null, IEnumerable <FieldExpression> fields = null, JoinType joinType = JoinType.Inner)
        {
            if (outer == null)
            {
                throw new ArgumentNullException(nameof(outer));
            }
            if (inner == null)
            {
                throw new ArgumentNullException(nameof(inner));
            }

            Outer     = outer;
            Inner     = inner;
            Predicate = predicate ?? new BooleanExpression(true);
            JoinType  = joinType;

            fields      = fields ?? outer.Fields.Concat(inner.Fields);
            Fields      = new FieldExpressions(this, fields);
            Expressions = new[] { outer, inner };
        }
Example #4
0
        /// <summary>
        /// Initializes a new instance of <see cref="SelectExpression"/> selecting the specified fields from the source.
        /// </summary>
        /// <param name="source">The source expression to select from.</param>
        /// <param name="fields">The fields to select from the source.</param>
        /// <param name="take">The number of fields to take from the source. Values less than zero indicate all rows.</param>
        /// <param name="skip">The number of fields to ignore on the source before reading rows.</param>
        /// <param name="orderings">The optional sorting of the selected rows.</param>
        /// <exception cref="ArgumentNullException">fields is null.</exception>
        /// <exception cref="ArgumentException">fields contains no elements or orderings contains duplicate field orderings.</exception>
        /// <exception cref="KeyNotFoundException">An ordering key could not be found in fields.</exception>
        public SelectExpression(ASourceExpression source, IEnumerable <FieldExpression> fields, int take = -1, int skip = 0, IEnumerable <Ordering> orderings = null)
        {
            if (fields == null)
            {
                throw new ArgumentNullException(nameof(fields));
            }
            if (!fields.Any())
            {
                throw new ArgumentException("There must be at least one field specified in a select query.", nameof(fields));
            }

            Source      = source;
            Fields      = new FieldExpressions(this, fields);
            Expressions = new[] { source };
            Take        = take;
            Skip        = skip;

            Orderings = orderings?
                        .Select(x =>
            {
                if (x == null)
                {
                    throw new ArgumentException("None of the ordering can be null.", nameof(orderings));
                }

                int count = orderings.Count(y => y.Field == x.Field);
                if (count != 1)
                {
                    throw new ArgumentException($"One ordering per field is allowed but '[{x.Field.TableName}].[{x.Field.FieldName}]' has {count}.", nameof(orderings));
                }
                if (!Fields.Any(y => y.SourceExpression == x.Field))
                {
                    throw new KeyNotFoundException($"The ordering field '[{x.Field.TableName}].[{x.Field.FieldName}]' could not be found in the fields parameter.");
                }

                return(x);
            })
                        .ToArray();
        }
        private IEnumerable <FieldExpression> DecodeJoinSelector(Expression expression, FieldExpressions outer, FieldExpressions inner)
        {
            // Get the associated lambda
            LambdaExpression lambda = StripQuotes(expression) as LambdaExpression;

            // Decode paramter body
            ParameterExpression parameter = lambda.Body as ParameterExpression;

            if (parameter != null)
            {
                if (parameter == lambda.Parameters[0])
                {
                    return(outer);
                }
                else if (parameter == lambda.Parameters[1])
                {
                    return(inner);
                }

                throw new InvalidOperationException($"The Join result selector does not recognise the specified '{parameter}' parameter. When using a paramter it must be one of the result selector paramter list.");
            }

            // Decode binary selector (It should always evaluate to all fields)
            BinaryExpression binary = lambda.Body as BinaryExpression;

            if (binary != null)
            {
                // Check the correct operator is being used
                if (binary.NodeType != ExpressionType.Or)
                {
                    throw new NotSupportedException("The only supported binary operator of an Sql Join call is Or: '|'.");
                }

                // Check the binary expressions are the paramters specified in the expression
                if (binary.Left != lambda.Parameters[0] && binary.Left != lambda.Parameters[1])
                {
                    throw new NotSupportedException("The left of the '|' operator in a Join result selector must be a parameter of the selector expression.");
                }
                if (binary.Right != lambda.Parameters[0] && binary.Right != lambda.Parameters[1])
                {
                    throw new NotSupportedException("The right of the '|' operator in a Join result selector must be a parameter of the selector expression.");
                }

                // Resolve select all
                if ((binary.Left == lambda.Parameters[0] && binary.Right == lambda.Parameters[1]) ||
                    (binary.Left == lambda.Parameters[1] && binary.Right == lambda.Parameters[0]))
                {
                    return(null);
                }

                throw new InvalidOperationException("The Join result selector should not select the same parameter more than once. e.g. '(o, i) => i | i' should be replaced with '(o, i) => i'.");
            }

            throw new NotSupportedException($"The Join result selctor does not know how to translate '{expression}' to SQL. The supported expressions are: '(o, i) => o', '(o, i) => i', '(o, i) => o | i' and '(o, i) => i | o'.");
        }
 private static ILookup <string, CommandField> GetFieldMap(this DbDataReader reader, FieldExpressions fields)
 {
     return(fields
            .Select(x => new CommandField(x.TableName, x.FieldName, reader.GetOrdinal(fields.GetKey(x))))
            .ToLookup(x => x.Table));
 }