private static void AppendCrossJoinApply(List <string> sqlLines, CrossApplyDefinition definition)
        {
            sqlLines.Append(
                $"CROSS APPLY OPENJSON({(definition.Parent == null ? "_doc._document" : "[" + definition.Parent.Name + "]")}, '$.{definition.Name}') WITH ([{definition.Path}] nvarchar(MAX) '$' AS JSON)");

            foreach (var childDefinition in definition.Children)
            {
                AppendCrossJoinApply(sqlLines, childDefinition);
            }
        }
        private static FieldType ResolveField(string originalPath, TypeReflector typeReflector, IDictionary <string, CrossApplyDefinition> crossApplyDefinitions, bool appendToGroupByClause = false)
        {
            var fieldTypes = typeReflector.Navigate(originalPath).ToList();

            if (!fieldTypes.Any())
            {
                throw new InvalidOperationException($"Property '{originalPath}' is invalid");
            }

            var resultingPath = new List <string>();
            var tempPath      = new List <string>();
            CrossApplyDefinition lastCrossApplyDefinition = null;

            foreach (var fieldType in fieldTypes)
            {
                if (fieldType.IsObjectArray)
                {
                    if (fieldType == fieldTypes.Last())
                    {
                        throw new InvalidOperationException();
                    }

                    tempPath.Add(fieldType.Name);

                    lastCrossApplyDefinition = new CrossApplyDefinition
                    {
                        Parent = fieldType.Parent?.Path != null ? crossApplyDefinitions[fieldType.Parent.Path] : null,
                        Name   = string.Join(".", tempPath)
                    };

                    crossApplyDefinitions[lastCrossApplyDefinition.Name] = lastCrossApplyDefinition;
                    if (appendToGroupByClause)
                    {
                        lastCrossApplyDefinition.AppendToGroupBy = true;
                    }

                    tempPath.Clear();
                }
                else
                {
                    resultingPath.Add(fieldType.Name);
                    tempPath.Add(fieldType.Name);
                }
            }

            return(new FieldType()
            {
                Type = fieldTypes.Last(),
                Path = string.Join(".", resultingPath),
                ParentField = lastCrossApplyDefinition?.Path ?? "_document"
            });
        }