/// Given a syntax of someField { fields, to, selection, from, object }
            /// it will figure out if 'someField' is an IEnumerable or an istance of the object (not a collection) and build the correct select statement
            private DataApiNode BuildDynamicSelectForObjectGraph(string query, string name, EqlGrammerParser.EntityQueryContext context)
            {
                if (!_schemaProvider.TypeHasField(_selectContext.Type.Name, name))
                {
                    throw new EqlCompilerException($"Type {_selectContext.Type} does not have field or property {name}");
                }
                name = _schemaProvider.GetActualFieldName(_selectContext.Type.Name, name);

                // Don't really like any of this, but...
                try
                {
                    var result = EqlCompiler.CompileWith(query, _selectContext, _schemaProvider, _methodProvider);
                    var exp    = result.Expression;
                    if (exp.Body.Type.IsEnumerable())
                    {
                        return(BuildDynamicSelectOnCollection(exp, name, context, false));
                    }

                    var oldContext = _selectContext;
                    _selectContext = exp.Body;
                    // visit child fields. Will be field or entityQueries again
                    var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList();

                    var relationsExps = fieldExpressions.Where(f => f.Expression.NodeType == ExpressionType.MemberInit || f.Expression.NodeType == ExpressionType.Call).ToList();
                    if (_relationHandler != null && relationsExps.Any())
                    {
                        var parameterExpression = Expression.Parameter(_selectContext.Type);
                        var relations           = relationsExps.Select(r => (Expression)Expression.PropertyOrField(parameterExpression, r.Name)).ToList();
                        exp = _relationHandler.BuildNodeForSelect(relations, parameterExpression, exp, name, _schemaProvider);
                    }

                    var newExp = DataApiExpressionUtil.CreateNewExpression(_selectContext, fieldExpressions, _schemaProvider);
                    _selectContext = oldContext;
                    return(new DataApiNode(_schemaProvider.GetActualFieldName(_selectContext.Type.Name, name), newExp, exp.Parameters.Any() ? exp.Parameters.First() : null, exp.Body));
                }
                catch (EqlCompilerException ex)
                {
                    throw DataApiException.MakeFieldCompileError(query, ex.Message);
                }
            }
            /// We compile each entityQuery with EqlCompiler and build a Select call from the fields
            public override DataApiNode VisitEntityQuery(EqlGrammerParser.EntityQueryContext context)
            {
                string name;
                string query;

                if (context.alias != null)
                {
                    name  = context.alias.name.GetText();
                    query = context.entity.GetText();
                }
                else
                {
                    query = context.entity.GetText();
                    name  = query;
                    if (name.IndexOf(".") > -1)
                    {
                        name = name.Substring(0, name.IndexOf("."));
                    }
                }

                try
                {
                    if (_selectContext == null)
                    {
                        // top level are queries on the context
                        var exp            = EqlCompiler.Compile(query, _schemaProvider, _methodProvider).Expression;
                        var topLevelSelect = BuildDynamicSelectOnCollection(exp, name, context, true);
                        return(topLevelSelect);
                    }
                    // other levels are object selection. e.g. from the top level people query I am selecting all their children { field1, etc. }
                    return(BuildDynamicSelectForObjectGraph(query, name, context));
                }
                catch (EqlCompilerException ex)
                {
                    //return DataApiNode.MakeError(name, $"Error compiling field or query '{query}'. {ex.Message}");
                    throw DataApiException.MakeFieldCompileError(query, ex.Message);
                }
            }