Exemplo n.º 1
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.º 2
0
        /// <summary>
        /// Visits IEnumerable.Contains
        /// </summary>
        private void VisitContains(QueryModel subQueryModel, ContainsResultOperator contains)
        {
            ResultBuilder.Append('(');

            var fromExpression = subQueryModel.MainFromClause.FromExpression;

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

            if (queryable != null)
            {
                Visit(contains.Item);

                ResultBuilder.Append(" IN (");
                if (_visitEntireSubQueryModel)
                {
                    _modelVisitor.VisitQueryModel(subQueryModel, false, true);
                }
                else
                {
                    _modelVisitor.VisitQueryModel(subQueryModel);
                }

                ResultBuilder.Append(')');
            }
            else
            {
                var inValues = ExpressionWalker.EvaluateEnumerableValues(fromExpression).ToArray();

                var hasNulls = inValues.Any(o => o == null);

                if (hasNulls)
                {
                    ResultBuilder.Append('(');
                }

                Visit(contains.Item);

                ResultBuilder.Append(" IN (");
                AppendInParameters(inValues);
                ResultBuilder.Append(')');

                if (hasNulls)
                {
                    ResultBuilder.Append(") OR ");
                    Visit(contains.Item);
                    ResultBuilder.Append(" IS NULL");
                }
            }

            ResultBuilder.Append(')');
        }