/// <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); }
protected override Expression VisitConditional(ConditionalExpression expression) { ResultBuilder.Append("casewhen("); Visit(expression.Test); // Explicit type specification is required when all arguments of CASEWHEN are parameters ResultBuilder.Append(", cast("); Visit(expression.IfTrue); ResultBuilder.AppendFormat(" as {0}), ", SqlTypes.GetSqlTypeName(expression.Type) ?? "other"); Visit(expression.IfFalse); ResultBuilder.Append(')'); return(expression); }