Exemplo n.º 1
0
        private Getter FormGetterByRelation(Relation relation, BoundingParameter[] parameters, out ParameterNames parameterNames,out Query query)
        {
            Getter getter;
            if (relation.HasTrivialQuery)
            {
                getter =
                    (keys, parPairs) =>
                    keys.Select(k => new KeyValuePair<Guid, IEnumerable<Guid>>(k, new[] {k})).ToArray();
                parameterNames = new ParameterNames(new string[0]);
                query = null;
            }
            else
            {
                var targetQuery =
                    relation.SelectTheBestQuery(parameters)
                        .FirstOrDefault();

                if (targetQuery == null)
                    throw new InvalidOperationException(
                        string.Format("Нет запроса для построения дерева: род. {0}, доч. {1} ",
                                      relation.ParentElement.Name,
                                      relation.ChildElement.Name));

                query = targetQuery;
                getter = (keys, parPairs) =>
                           targetQuery.GetMultipleChildResourceQuery(relation.ParentElement.Name,
                                                             parPairs.Keys.ToArray())(keys,parPairs.Values.ToArray());
                parameterNames = new ParameterNames(targetQuery.Arguments.Where(k=>!StringComparer.InvariantCultureIgnoreCase.Equals(k,relation.ParentElement.Name)));
            }
            return getter;
        }
Exemplo n.º 2
0
 public IEnumerable<Query> SelectTheBestQuery(BoundingParameter[] parameters)
 {            
     var paramsWithoutResource = parameters;
     var rankedQueries = Queries.Select(k => new { rank = CalcQueryRank(k, ParentElement.Name, paramsWithoutResource), query = k }).ToArray();
     var bestQuery = rankedQueries.Where(k => k.rank >= 0)
                                  .OrderByDescending(k => k.rank)
                                  .Select(k => k.query);
     return bestQuery;
 }
Exemplo n.º 3
0
        private static double CalcQueryRank(Query query, string parentName, BoundingParameter[] parameters)
        {

            Func<string, string, bool> equals =
                (a, b) => string.Equals(a, b, StringComparison.InvariantCultureIgnoreCase);

            //отсев запросов, у которых есть параметры, не являющиеся родительским параметром или одним параметром из списка
            if (query.Arguments
                     .Where(k => !equals(k, parentName))
                     .Any(k => parameters.All(k2 => !equals(k2.Name, k))))
                return -1;

            double rank = 0.1;


            if (query.Arguments.Contains(parentName) && query.ArgCount == 1)
            {
                rank = 0.5;
            }
            else if (parameters.Length != 0)
            {
                var correctiveFloor = parameters.Max(k => k.Depth);
                //нужно перевести глубину параметров от текущей точки в рейтинг для текущей точки, т.е. перевернуть их все
                rank =
                   query.Arguments.Where(k => !equals(k, parentName)).Select(
                       k => correctiveFloor - parameters.Single(k2 => equals(k2.Name, k)).Depth + 1).Sum();
            }

            if (query.Arguments.Contains(parentName))
            {


                rank *= 2;

                if (query.SerialQueryIsPreferred(parentName))
                    rank += 1;
            }

            if (!string.IsNullOrEmpty(query.Namespace))
                rank *= 100;
            return rank;
        }
Exemplo n.º 4
0
        private IEnumerable <PrimaryFrameNode> MakeAllPossibleWaysRec(List <string> processed, ProjectionElement element, SortedSet <BoundingParameter> orderedParameters, int depth)
        {
            if (depth == int.MinValue)
            {
                throw new InvalidOperationException("Ошибка при построении плана - слишком глубокая схема для разбора");
            }
            if (depth == 0)
            {
                return(new PrimaryFrameNode[0]);
            }

            #region Проверка - был ли проверен текущий элемент, и добавление его к проверенным

            var hash = GetHashForElementAndParameters(element, new ParameterNames(orderedParameters.Select(k => k.Name)));


            if (processed.Contains(hash))
            {
                return(new PrimaryFrameNode[0]);
            }

            processed.Add(hash);


            #endregion

            #region Добавление текущего элемента к родительским параметрам или обнуление глубины уже существующего параметра с данным именем

            foreach (var p in orderedParameters)
            {
                p.Depth++;
            }

            var parameter = orderedParameters.FirstOrDefault(k => k.Name == element.Name);
            int oldDepth;
            if (parameter == null)
            {
                parameter = new BoundingParameter(element.Name, 1);
                orderedParameters.Add(parameter);
                oldDepth = 0;
            }
            else
            {
                oldDepth        = parameter.Depth;
                parameter.Depth = 1;
            }

            #endregion

            #region Обход детей дочерних нод

            var childElements = element.DownRelations
                                .Select(k => new
            {
                relation = k,
                k.ChildElement,
                children =
                    MakeAllPossibleWaysRec(processed, k.ChildElement, orderedParameters, depth - 1)
            }).ToArray();

            #endregion



            processed.Remove(hash);

            if (oldDepth == 0)
            {
                orderedParameters.Remove(parameter);
            }
            else
            {
                parameter.Depth = oldDepth;
            }


            #region Формирование списка нод вместе с дочерними

            var allNodes = childElements.Select(k =>
                                                new PrimaryFrameNode
            {
                Current           = k.ChildElement,
                OrderedParameters =
                    orderedParameters.Where(k2 => !StringComparer.InvariantCultureIgnoreCase.Equals(k2.Name, element.Name))
                    .Select(k2 => new BoundingParameter(k2.Name, k2.Depth))
                    .ToArray(),
                Parent   = element,
                Relation = k.relation
            })
                           .Concat(childElements.SelectMany(k => k.children))
                           .ToArray();

            #endregion


            foreach (var p in orderedParameters)
            {
                p.Depth--;
            }

            return(allNodes);
        }
Exemplo n.º 5
0
        private IEnumerable<PrimaryFrameNode> MakeAllPossibleWaysRec(List<string> processed, ProjectionElement element, SortedSet<BoundingParameter> orderedParameters, int depth)
        {
            if (depth == int.MinValue)
                throw new InvalidOperationException("Ошибка при построении плана - слишком глубокая схема для разбора");
            if (depth == 0)
                return new PrimaryFrameNode[0];

            #region Проверка - был ли проверен текущий элемент, и добавление его к проверенным

            var hash = GetHashForElementAndParameters(element, new ParameterNames(orderedParameters.Select(k => k.Name)));

           
                if (processed.Contains(hash))
                    return new PrimaryFrameNode[0];

                processed.Add(hash);
            

            #endregion

            #region Добавление текущего элемента к родительским параметрам или обнуление глубины уже существующего параметра с данным именем

            foreach (var p in orderedParameters)
            {
                p.Depth++;
            }

            var parameter = orderedParameters.FirstOrDefault(k => k.Name == element.Name);
            int oldDepth;
            if (parameter == null)
            {
                parameter = new BoundingParameter(element.Name, 1);
                orderedParameters.Add(parameter);
                oldDepth = 0;
            }
            else
            {
                oldDepth = parameter.Depth;
                parameter.Depth = 1;
            }

            #endregion

            #region Обход детей дочерних нод

            var childElements = element.DownRelations
                .Select(k => new
                                 {
                                     relation = k,
                                     k.ChildElement,
                                     children =
                                 MakeAllPossibleWaysRec(processed, k.ChildElement, orderedParameters, depth - 1)
                                 }).ToArray();

            #endregion



            processed.Remove(hash);

            if (oldDepth == 0)
                orderedParameters.Remove(parameter);
            else
            {
                parameter.Depth = oldDepth;
            }


            #region Формирование списка нод вместе с дочерними

            var allNodes = childElements.Select(k =>
                                                new PrimaryFrameNode
                                                    {
                                                        Current = k.ChildElement,
                                                        OrderedParameters =
                                                            orderedParameters.Where(k2=>!StringComparer.InvariantCultureIgnoreCase.Equals(k2.Name,element.Name))
                                                                             .Select(k2 => new BoundingParameter(k2.Name, k2.Depth))
                                                                             .ToArray(),
                                                        Parent = element,
                                                        Relation = k.relation
                                                    })
                .Concat(childElements.SelectMany(k => k.children))
                .ToArray();

            #endregion


            foreach (var p in orderedParameters)
            {
                p.Depth--;
            }
          
            return allNodes;
        }
Exemplo n.º 6
0
 public Getter FormGetter(Relation relation, BoundingParameter[] parameters, out ParameterNames parameterNames)
 {
     var testBuilder = new FramingPlanBuilder();
     Query query;
     return testBuilder.FormGetterByRelation(relation, parameters,out parameterNames,out query);
 }