public override SqlFragment Visit()

in EntityFramework/src/Generators/SelectGenerator.cs [222:346]


    public override SqlFragment Visit(DbApplyExpression expression)
    {

      DbExpressionBinding inputBinding = expression.Input;
      InputFragment input = VisitInputExpression(inputBinding.Expression, inputBinding.VariableName, inputBinding.VariableType);
      DbExpressionBinding applyBinding = expression.Apply;
      InputFragment apply = VisitInputExpression(applyBinding.Expression, applyBinding.VariableName, applyBinding.VariableType);
      SelectStatement select = new SelectStatement(this);
      bool isInputSelect = false;
      if (!(input is TableFragment))
      {
        input.Wrap(scope);
        isInputSelect = true;
      }
      apply.Wrap(scope);
      select.From = input;
      select.Wrap(scope);
      if (apply is SelectStatement)
      {
        SelectStatement applySel = apply as SelectStatement;
        foreach (ColumnFragment f in applySel.Columns)
        {
          SelectStatement newColSelect = new SelectStatement(this);
          newColSelect.From = applySel.From;
          newColSelect.Where = applySel.Where;
          if (isInputSelect)
          {
            VisitAndReplaceTableName(newColSelect.Where, (input as SelectStatement).From.Name, input.Name, null);
          }
          newColSelect.Limit = applySel.Limit;
          newColSelect.OrderBy = applySel.OrderBy;
          newColSelect.Skip = applySel.Skip;
          newColSelect.GroupBy = applySel.GroupBy;
          newColSelect.IsDistinct = applySel.IsDistinct;
          newColSelect.Columns.Add(f);

          newColSelect.Wrap(scope);
          scope.Add(applySel.From.Name, applySel.From);

          ColumnFragment newCol = new ColumnFragment(apply.Name, f.ColumnName);
          newCol.Literal = newColSelect;
          newCol.PushInput(newCol.ColumnName);
          newCol.PushInput(apply.Name);
          select.AddColumn(newCol, scope);
          if (string.IsNullOrEmpty(newCol.ColumnAlias))
          {
            newColSelect.Name = newCol.ColumnName;
            newCol.ColumnAlias = newCol.ColumnName;
          }
          scope.Remove(newColSelect);
        }
        scope.Remove(applySel.From);
        scope.Remove(apply);
      }
      else if (apply is UnionFragment)
      {
        UnionFragment uf = apply as UnionFragment;
        if (uf.Left == null || uf.Right == null)
          throw new Exception("Union fragment is not properly formed.");

        var left = uf.Left as SelectStatement;
        var right = uf.Right as SelectStatement;

        if (left == null || right == null)
          throw new NotImplementedException();

        var whereleft = left.Where as BinaryFragment;
        var whereright = right.Where as BinaryFragment;

        if (whereleft == null || whereright == null)
          throw new NotImplementedException();
        
        LiteralFragment literalFragmentWhere = null;        

        //checking where left
        if (whereleft.Left is ColumnFragment && whereleft.Right is ColumnFragment)
        {
          // we replace the where part for a dummy one 
          if (whereright.Left is ColumnFragment && whereright.Right is ColumnFragment)
          {
            literalFragmentWhere = new LiteralFragment("1 = 1");               
          }
        }

        if (literalFragmentWhere == null)
          throw new NotImplementedException();

        var leftouterjoin = new JoinFragment();
        leftouterjoin.JoinType = Metadata.GetOperator(DbExpressionKind.LeftOuterJoin);
        leftouterjoin.Name = apply.Name;        

        // validating that column fragment on the left matches the name
        // for the input fragment
        var leftColumnFragment = whereleft.Left as ColumnFragment;

        if (leftColumnFragment == null)
          throw new NotImplementedException();

        if (!leftColumnFragment.TableName.Equals(input.Name))
          new NotImplementedException();

        var conditionJoin = new BinaryFragment();
        conditionJoin.Left = whereleft.Left;

        //update to the new reference
        var newColumnFragment = whereright.Right as ColumnFragment;
        if (newColumnFragment != null)
        {          
          newColumnFragment.TableName = uf.Name;
        }
        conditionJoin.Right = newColumnFragment;
        conditionJoin.Operator = whereleft.Operator;

        leftouterjoin.Condition = conditionJoin;

        (uf.Left as SelectStatement).Where = literalFragmentWhere;
        (uf.Right as SelectStatement).Where = literalFragmentWhere;
        
        leftouterjoin.Left = input;
        leftouterjoin.Right = uf;

        return leftouterjoin;
      }
      return select;
    }