UnresolvedGroupReferenceTableInfo constitutes an implementation of ITableInfo for data sources returning items from a sequence produced by another SqlTable called the ReferencedGroupSource.
상속: ITableInfo
 ITableInfo ITableInfoVisitor.VisitUnresolvedGroupReferenceTableInfo (UnresolvedGroupReferenceTableInfo tableInfo)
 {
   throw new InvalidOperationException ("UnresolvedGroupReferenceTableInfo is not valid at this point.");
 }
    public Expression VisitSqlTableReferenceExpression (SqlTableReferenceExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var tableInfo = new UnresolvedGroupReferenceTableInfo (expression.SqlTable);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);
      FromExpressionInfo = new FromExpressionInfo (sqlTable, new Ordering[0], new SqlTableReferenceExpression (sqlTable), null);

      return 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 ResolveTableInfo_GroupReferenceTableInfo_NoGorupingSubStatement ()
    {
      var subStatement = SqlStatementModelObjectMother.CreateSqlStatement (Expression.Constant (new int[0]));
      var groupSource = SqlStatementModelObjectMother.CreateSqlTable (new ResolvedSubStatementTableInfo ("q0", subStatement));
      var tableInfo = new UnresolvedGroupReferenceTableInfo (groupSource);

      ResolvingTableInfoVisitor.ResolveTableInfo (tableInfo, _resolverMock, _generator, _stageMock, _mappingResolutionContext);
    }
    public void ResolveTableInfo_GroupReferenceTableInfo_NoSubStatement ()
    {
      var groupSource = SqlStatementModelObjectMother.CreateSqlTable_WithResolvedTableInfo (typeof (IEnumerable<Cook>));
      var tableInfo = new UnresolvedGroupReferenceTableInfo (groupSource);

      ResolvingTableInfoVisitor.ResolveTableInfo (tableInfo, _resolverMock, _generator, _stageMock, _mappingResolutionContext);
    }
    public void ResolveTableInfo_GroupReferenceTableInfo ()
    {
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook));
      var groupingSelect = new SqlGroupingSelectExpression (
          Expression.MakeMemberAccess (new SqlTableReferenceExpression (sqlTable), typeof (Cook).GetProperty ("Name")),
          Expression.MakeMemberAccess (new SqlTableReferenceExpression (sqlTable), typeof (Cook).GetProperty ("ID")));
      var dataInfo = new StreamedSequenceInfo (
          typeof (IEnumerable<>).MakeGenericType (groupingSelect.Type), 
          Expression.Constant (null, groupingSelect.Type));
      var whereCondition = Expression.Constant (false);
      var groupByExpression = groupingSelect.KeyExpression;
      var groupingSubStatement = new SqlStatementBuilder
                                 {
                                     DataInfo = dataInfo,
                                     SelectProjection = groupingSelect,
                                     SqlTables = { sqlTable },
                                     WhereCondition = whereCondition,
                                     GroupByExpression = groupByExpression
                                 }.GetSqlStatement();
      var groupSource = SqlStatementModelObjectMother.CreateSqlTable (new ResolvedSubStatementTableInfo ("q0", groupingSubStatement));
      var tableInfo = new UnresolvedGroupReferenceTableInfo (groupSource);

      var expectedKeyViaElement = Expression.MakeMemberAccess (new SqlTableReferenceExpression (sqlTable), typeof (Cook).GetProperty ("Name"));
      var expectedKeyViaGroupSource = Expression.MakeMemberAccess (new SqlTableReferenceExpression (groupSource), groupSource.ItemType.GetProperty ("Key"));
      
      var expectedResultWhereCondition =
          Expression.OrElse (
              Expression.AndAlso (new SqlIsNullExpression (expectedKeyViaElement), new SqlIsNullExpression (expectedKeyViaGroupSource)),
              Expression.AndAlso (
                  Expression.AndAlso (new SqlIsNotNullExpression (expectedKeyViaElement), new SqlIsNotNullExpression (expectedKeyViaGroupSource)),
                  Expression.Equal (expectedKeyViaElement, expectedKeyViaGroupSource)));
      
      var fakeWhereCondition = Expression.Constant (false);
      _stageMock
          .Expect (mock => mock.ResolveWhereExpression (Arg<Expression>.Is.Anything, Arg.Is (_mappingResolutionContext)))
          .WhenCalled (mi => SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResultWhereCondition, (Expression) mi.Arguments[0]))
          .Return (fakeWhereCondition);
      _stageMock.Replay();

      var result = ResolvingTableInfoVisitor.ResolveTableInfo (tableInfo, _resolverMock, _generator, _stageMock, _mappingResolutionContext);

      _stageMock.VerifyAllExpectations();

      Assert.That (result, Is.TypeOf (typeof (ResolvedJoinedGroupingTableInfo)));

      var castResult = ((ResolvedJoinedGroupingTableInfo) result);
      
      var resultGroupingSelector = castResult.AssociatedGroupingSelectExpression;
      Assert.That (resultGroupingSelector, Is.SameAs (groupingSelect));

      Assert.That (castResult.GroupSourceTableAlias, Is.EqualTo ("q0"));
      
      var resultSqlStatement = castResult.SqlStatement;

      Assert.That (resultSqlStatement.SqlTables, Is.EqualTo (groupingSubStatement.SqlTables));
      Assert.That (resultSqlStatement.Orderings, Is.Empty);
      Assert.That (resultSqlStatement.GroupByExpression, Is.Null);
      
      SqlExpressionTreeComparer.CheckAreEqualTrees (
          Expression.AndAlso (groupingSubStatement.WhereCondition, fakeWhereCondition), 
          resultSqlStatement.WhereCondition);

      var expectedResultSelectProjection =
          Expression.MakeMemberAccess (new SqlTableReferenceExpression (resultSqlStatement.SqlTables[0]), typeof (Cook).GetProperty ("ID"));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResultSelectProjection, resultSqlStatement.SelectProjection);

      Assert.That (resultSqlStatement.DataInfo, Is.TypeOf (typeof (StreamedSequenceInfo)));
      Assert.That (resultSqlStatement.DataInfo.DataType, Is.SameAs (typeof (IQueryable<int>)));

      var expectedItemExpression = resultSqlStatement.SelectProjection;
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedItemExpression, ((StreamedSequenceInfo) resultSqlStatement.DataInfo).ItemExpression);
    }
 public void SetUp ()
 {
   _referencedGroupSource = SqlStatementModelObjectMother.CreateSqlTable (typeof (IGrouping<int, string>));
   _tableInfo = new UnresolvedGroupReferenceTableInfo (_referencedGroupSource);
 }