RecalculateDataInfo() public method

public RecalculateDataInfo ( Expression previousSelectProjection ) : void
previousSelectProjection System.Linq.Expressions.Expression
return void
    public SqlStatement VisitSqlStatement (SqlStatement sqlStatement, SqlExpressionContext expressionContext)
    {
      ArgumentUtility.CheckNotNull ("sqlStatement", sqlStatement);

      if (expressionContext == SqlExpressionContext.PredicateRequired)
        throw new InvalidOperationException ("A SqlStatement cannot be used as a predicate.");

      var statementBuilder = new SqlStatementBuilder (sqlStatement);

      var newSelectProjection = _stage.ApplyContext (sqlStatement.SelectProjection, expressionContext, _mappingResolutionContext);
      statementBuilder.SelectProjection = newSelectProjection;
      statementBuilder.RecalculateDataInfo (sqlStatement.SelectProjection);

      var newSqlStatement = statementBuilder.GetSqlStatement();
      return newSqlStatement.Equals (sqlStatement) ? sqlStatement : newSqlStatement;
    }
    private SqlTable CreateSqlCompatibleSubStatementTable (
        SqlStatement originalStatement, 
        Expression newSelectProjection, 
        Func<ITableInfo, SqlTable> tableCreator)
    {
      // create a new statement equal to the original one, but with the tuple as its select projection
      var builder = new SqlStatementBuilder (originalStatement) { SelectProjection = newSelectProjection };
      builder.RecalculateDataInfo (originalStatement.SelectProjection);

      // clear orderings unless required for TopExpression
      if (originalStatement.TopExpression == null)
        builder.Orderings.Clear();
        
      var newSqlStatement = builder.GetSqlStatement();

      // put new statement into a sub-statement table
      var subStatementTableInfo = new ResolvedSubStatementTableInfo (_uniqueIdentifierGenerator.GetUniqueIdentifier ("q"), newSqlStatement);
      return tableCreator (subStatementTableInfo);
    }
    private Expression CheckAndSimplifyEntityWithinSubStatement (SqlSubStatementExpression sqlSubStatementExpression)
    {
      var newSelectProjection = ResolvePotentialEntity (sqlSubStatementExpression.SqlStatement.SelectProjection);
      if (newSelectProjection != sqlSubStatementExpression.SqlStatement.SelectProjection)
      {
        var newSubStatement = new SqlStatementBuilder (sqlSubStatementExpression.SqlStatement) { SelectProjection = newSelectProjection };
        newSubStatement.RecalculateDataInfo (sqlSubStatementExpression.SqlStatement.SelectProjection);

        return newSubStatement.GetSqlStatement ().CreateExpression ();
      }

      return sqlSubStatementExpression;
    }
    protected override Expression VisitMemberExpression (MemberExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var newInnerExpression = VisitExpression (expression.Expression);

      var innerExpressionAsSqlCaseExpression = newInnerExpression as SqlCaseExpression;
      if (innerExpressionAsSqlCaseExpression != null)
      {
        var originalCases = innerExpressionAsSqlCaseExpression.Cases;
        var originalElseCase = innerExpressionAsSqlCaseExpression.ElseCase;
        var newCases = originalCases.Select (c => new SqlCaseExpression.CaseWhenPair (c.When, Expression.MakeMemberAccess (c.Then, expression.Member)));
        var newElseCase = originalElseCase != null ? Expression.MakeMemberAccess (originalElseCase, expression.Member) : null;
        // If there is no else case, ensure that the resulting type is nullable
        var caseExpressionType =
            newElseCase == null && expression.Type.IsValueType && Nullable.GetUnderlyingType (expression.Type) == null
                ? typeof (Nullable<>).MakeGenericType (expression.Type)
                : expression.Type;
        var newSqlCaseExpression = new SqlCaseExpression (caseExpressionType, newCases, newElseCase);
        return VisitExpression (newSqlCaseExpression);
      }

      if (newInnerExpression.NodeType == ExpressionType.Coalesce)
      {
        var innerExpressionAsBinaryExpression = (BinaryExpression) newInnerExpression;
        var newConditionalExpression = Expression.Condition (
            new SqlIsNotNullExpression (innerExpressionAsBinaryExpression.Left), 
            Expression.MakeMemberAccess (innerExpressionAsBinaryExpression.Left, expression.Member), 
            Expression.MakeMemberAccess (innerExpressionAsBinaryExpression.Right, expression.Member));
        return VisitExpression (newConditionalExpression);
      }

      var innerExpressionAsSqlSubStatementExpression = newInnerExpression as SqlSubStatementExpression;
      if (innerExpressionAsSqlSubStatementExpression != null)
      {
        var sqlStatementBuilder = new SqlStatementBuilder (innerExpressionAsSqlSubStatementExpression.SqlStatement);
        var namedExpression = (NamedExpression) sqlStatementBuilder.SelectProjection;
        sqlStatementBuilder.SelectProjection = new NamedExpression (
            namedExpression.Name, VisitExpression (Expression.MakeMemberAccess (namedExpression.Expression, expression.Member)));
        sqlStatementBuilder.RecalculateDataInfo (innerExpressionAsSqlSubStatementExpression.SqlStatement.SelectProjection);
        return new SqlSubStatementExpression (sqlStatementBuilder.GetSqlStatement());
      }

      var memberAsPropertyInfo = expression.Member as PropertyInfo;
      if (memberAsPropertyInfo != null)
      {
        var methodInfo = memberAsPropertyInfo.GetGetMethod();
        if (methodInfo != null)
        {
          var methodCallExpression = Expression.Call (expression.Expression, methodInfo);
          var tranformer = _methodCallTransformerProvider.GetTransformer(methodCallExpression);
          if (tranformer != null)
          {
            var tranformedExpression = tranformer.Transform (methodCallExpression);
            return VisitExpression (tranformedExpression);
          }
        }
      }
      return base.VisitMemberExpression (expression);
    }
    public ITableInfo VisitUnresolvedGroupReferenceTableInfo (UnresolvedGroupReferenceTableInfo tableInfo)
    {
      var groupSourceSubStatementTableInfo = tableInfo.ReferencedGroupSource.GetResolvedTableInfo() as ResolvedSubStatementTableInfo;
      if (groupSourceSubStatementTableInfo == null)
      {
        var message = string.Format (
            "This SQL generator only supports sequences in from expressions if they are members of an entity or if they come from a GroupBy operator. "
            + "Sequence: '{0}'", tableInfo);
        throw new NotSupportedException (message);
      }

      var groupingSelectExpression = groupSourceSubStatementTableInfo.SqlStatement.SelectProjection as SqlGroupingSelectExpression;
      if (groupingSelectExpression == null)
      {
        throw new NotSupportedException (
            "When a sequence retrieved by a subquery is used in a from expression, the subquery must end with a GroupBy operator.");
      }

      var elementSelectingStatementBuilder = new SqlStatementBuilder (groupSourceSubStatementTableInfo.SqlStatement) { GroupByExpression = null };

      var currentKeyExpression = Expression.MakeMemberAccess (
          new SqlTableReferenceExpression (tableInfo.ReferencedGroupSource), 
          groupingSelectExpression.Type.GetProperty ("Key"));

      var groupKeyJoinCondition = _stage.ResolveWhereExpression (
          Expression.OrElse (
              Expression.AndAlso (new SqlIsNullExpression (groupingSelectExpression.KeyExpression), new SqlIsNullExpression (currentKeyExpression)),
              Expression.AndAlso (
                  Expression.AndAlso (
                      new SqlIsNotNullExpression (groupingSelectExpression.KeyExpression), 
                      new SqlIsNotNullExpression (currentKeyExpression)),
                  Expression.Equal (groupingSelectExpression.KeyExpression, currentKeyExpression))), 
          _context);
      elementSelectingStatementBuilder.AddWhereCondition (groupKeyJoinCondition);

      elementSelectingStatementBuilder.SelectProjection = groupingSelectExpression.ElementExpression;
      elementSelectingStatementBuilder.RecalculateDataInfo (groupingSelectExpression);

      return new ResolvedJoinedGroupingTableInfo (
          _generator.GetUniqueIdentifier("q"), 
          elementSelectingStatementBuilder.GetSqlStatement(), 
          groupingSelectExpression,
          groupSourceSubStatementTableInfo.TableAlias);
    }
    public void RecalculateDataInfo_UnchangedProjectionType_SameDataInfo ()
    {
      var statementBuilder = new SqlStatementBuilder ();

      var previousSelectProjection = Expression.Constant ("test");
      var originalDataInfo = new StreamedSingleValueInfo (typeof(string), false);
      statementBuilder.DataInfo = originalDataInfo;
      statementBuilder.SelectProjection = new SqlColumnDefinitionExpression (typeof (string), "c", "Length", false);

      statementBuilder.RecalculateDataInfo (previousSelectProjection);

      Assert.That (statementBuilder.DataInfo, Is.SameAs (originalDataInfo));
    }
    public void RecalculateDataInfo_WithOtherDataInfo_ReturnsSameDataInfo ()
    {
      var statementBuilder = new SqlStatementBuilder ();

      var previousSelectProjection = Expression.Constant ("test");
      var originalDataInfo = new TestStreamedValueInfo(typeof(string));
      statementBuilder.DataInfo = originalDataInfo;
      statementBuilder.SelectProjection = new SqlColumnDefinitionExpression (typeof (int), "c", "Length", false);

      statementBuilder.RecalculateDataInfo (previousSelectProjection);

      Assert.That (statementBuilder.DataInfo, Is.SameAs (originalDataInfo));
    }
    public void RecalculateDataInfo_StreamedScalarValueInfo_ReturnsSameDataInfo ()
    {
      var statementBuilder = new SqlStatementBuilder ();

      var previousSelectProjection = Expression.Constant ("test");
      statementBuilder.DataInfo = new StreamedScalarValueInfo(typeof(string));
      statementBuilder.SelectProjection = new SqlColumnDefinitionExpression (typeof (int), "c", "Length", false);

      statementBuilder.RecalculateDataInfo (previousSelectProjection);

      Assert.That (statementBuilder.DataInfo, Is.TypeOf (typeof (StreamedScalarValueInfo)));
      Assert.That (((StreamedScalarValueInfo) statementBuilder.DataInfo).DataType, Is.EqualTo (typeof (string)));
    }
    public void RecalculateDataInfo_StreamedSequenceInfo ()
    {
      var statementBuilder = new SqlStatementBuilder ();

      var previousSelectProjection = Expression.Constant (typeof (Restaurant));
      statementBuilder.DataInfo = new StreamedSequenceInfo (typeof (IQueryable<>).MakeGenericType (typeof (Restaurant)), Expression.Constant (new Restaurant()));
      statementBuilder.SelectProjection = new SqlColumnDefinitionExpression (typeof (string), "c", "Name", false);

      statementBuilder.RecalculateDataInfo(previousSelectProjection);

      Assert.That (statementBuilder.DataInfo, Is.TypeOf (typeof (StreamedSequenceInfo)));
      Assert.That (((StreamedSequenceInfo) statementBuilder.DataInfo).DataType, Is.EqualTo(typeof (IQueryable<>).MakeGenericType(typeof(string))));
    }