Exemplo n.º 1
0
        protected override Expression VisitMember(MemberExpression expression)
        {
            // Field hierarchy is flattened (Person.Address.Street is just Street), append as is, do not call Visit.

            // Property call (string.Length, DateTime.Month, etc).
            if (MethodVisitor.VisitPropertyCall(expression, this))
            {
                return(expression);
            }

            // Special case: grouping
            if (VisitGroupByMember(expression.Expression))
            {
                return(expression);
            }

            var queryable = ExpressionWalker.GetCacheQueryable(expression, false);

            if (queryable != null)
            {
                // Find where the projection comes from.
                expression = ExpressionWalker.GetProjectedMember(expression.Expression, expression.Member) ??
                             expression;

                var fieldName = GetEscapedFieldName(expression, queryable);

                ResultBuilder.AppendFormat("{0}.{1}", Aliases.GetTableAlias(expression), fieldName);
            }
            else
            {
                AppendParameter(ExpressionWalker.EvaluateExpression <object>(expression));
            }

            return(expression);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Visists Join clause in case of join with local collection
        /// </summary>
        private void VisitJoinWithLocalCollectionClause(JoinClause joinClause)
        {
            var type = joinClause.InnerSequence.Type;

            var itemType = EnumerableHelper.GetIEnumerableItemType(type);

            var sqlTypeName = SqlTypes.GetSqlTypeName(itemType);

            if (string.IsNullOrWhiteSpace(sqlTypeName))
            {
                throw new NotSupportedException("Not supported item type for Join with local collection: " + type.Name);
            }

            var    isOuter            = false;
            var    sequenceExpression = joinClause.InnerSequence;
            object values;

            var subQuery = sequenceExpression as SubQueryExpression;

            if (subQuery != null)
            {
                isOuter            = subQuery.QueryModel.ResultOperators.OfType <DefaultIfEmptyResultOperator>().Any();
                sequenceExpression = subQuery.QueryModel.MainFromClause.FromExpression;
            }

            switch (sequenceExpression.NodeType)
            {
            case ExpressionType.Constant:
                var constantValueType = ((ConstantExpression)sequenceExpression).Value.GetType();
                if (constantValueType.IsGenericType)
                {
                    isOuter = DefaultIfEmptyEnumeratorType == constantValueType.GetGenericTypeDefinition();
                }
                values = ExpressionWalker.EvaluateEnumerableValues(sequenceExpression);
                break;

            case ExpressionType.Parameter:
                values = ExpressionWalker.EvaluateExpression <object>(sequenceExpression);
                break;

            default:
                throw new NotSupportedException("Expression not supported for Join with local collection: "
                                                + sequenceExpression);
            }

            var tableAlias = _aliases.GetTableAlias(joinClause);
            var fieldAlias = _aliases.GetFieldAlias(joinClause.InnerKeySelector);

            _builder.AppendFormat("{0} join table ({1} {2} = ?) {3} on (",
                                  isOuter ? "left outer" : "inner",
                                  fieldAlias,
                                  sqlTypeName,
                                  tableAlias);

            Parameters.Add(values);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Visits the SQL like expression.
        /// </summary>
        private static void VisitSqlLike(MethodCallExpression expression, CacheQueryExpressionVisitor visitor,
                                         string likeFormat)
        {
            visitor.ResultBuilder.Append("(");

            visitor.Visit(expression.Object);

            visitor.ResultBuilder.AppendFormat(" like {0}) ", likeFormat);

            var arg = expression.Arguments[0] as ConstantExpression;

            var paramValue = arg != null
                ? arg.Value
                : ExpressionWalker.EvaluateExpression <object>(expression.Arguments[0]);

            visitor.Parameters.Add(paramValue);
        }
        /// <summary>
        /// Gets values for IN expression.
        /// </summary>
        private static IEnumerable <object> GetInValues(Expression fromExpression)
        {
            IEnumerable result;

            switch (fromExpression.NodeType)
            {
            case ExpressionType.MemberAccess:
                var memberExpression = (MemberExpression)fromExpression;
                result = ExpressionWalker.EvaluateExpression <IEnumerable>(memberExpression);
                break;

            case ExpressionType.ListInit:
                var listInitExpression = (ListInitExpression)fromExpression;
                result = listInitExpression.Initializers
                         .SelectMany(init => init.Arguments)
                         .Select(ExpressionWalker.EvaluateExpression <object>);
                break;

            case ExpressionType.NewArrayInit:
                var newArrayExpression = (NewArrayExpression)fromExpression;
                result = newArrayExpression.Expressions
                         .Select(ExpressionWalker.EvaluateExpression <object>);
                break;

            case ExpressionType.Parameter:
                // This should happen only when 'IEnumerable.Contains' is called on parameter of compiled query
                throw new NotSupportedException("'Contains' clause coming from compiled query parameter is not supported.");

            default:
                result = Expression.Lambda(fromExpression).Compile().DynamicInvoke() as IEnumerable;
                break;
            }

            result = result ?? Enumerable.Empty <object>();

            return(result
                   .Cast <object>()
                   .ToArray());
        }
        /// <summary>
        /// Registers query parameter that is evaluated from a lambda expression argument.
        /// </summary>
        public object RegisterEvaluatedParameter(Expression expression)
        {
            _modelVisitor.ParameterExpressions.Add(expression);

            return(ExpressionWalker.EvaluateExpression <object>(expression));
        }